spinner 类线程错误 - 只允许一个线程

发布于 2024-12-19 00:39:55 字数 1437 浏览 0 评论 0原文

我已经问了一个关于这个的问题 昨天,但现在我有了另一个:)我正在尝试编写一个文本效果类型类供我的终端应用程序使用 - 它可以执行诸如定位光标、清除屏幕、回显字符串内的颜色选择(颜色前面带有“@”)之类的操作, 随机情况, 颜色骑自行车和其他有趣的东西(部分是为了帮助我学习 python,部分是为了实用)——如果我想让我的课程的一部分不是一个线程,我会怎么做?目前我有这个旋转器正在工作(整个代码此处),但我想多次调用它。像这样:

s=spin()
s.echo('@@') # clears screen
# at the moment - here i get an error because only one thread can be started
s.echo('@red this is red @green green etc...')

echo 函数做了很多事情,如果你查看 Pastebin,你会发现,所以我需要调用它很多次,但多次调用会导致“仅一个线程”允许错误。也许我应该用不同的方式来做。这是在 Pastebin 之前的基本旧代码。

spinner="▏▎▍▌▋▊▉█▉▊▌▍▎" #utf8

#convert the utf8 spinner string to a list
chars=[c.encode("utf-8") for c in unicode(spinner,"utf-8")]

class spin(threading.Thread):

    def __init__(self):
        super(spin,self).__init__()
        self._stop = False

    def run (self):
        pos=0
        while not self._stop:
            sys.stdout.write("\r"+chars[pos])
            sys.stdout.flush()
            time.sleep(.15)
            pos+=1
            pos%=len(chars)

    def cursor_visible(self):
        os.system("tput cvvis")
    def cursor_invisible(self):
        os.system("tput civis")
    def stop(self):
        self._stop = True
    def stopped(self):
        return self._stop == True

I already asked a question about this yesterday, but now I have another :) im trying to write a text effects type class for my terminal apps to use - it does stuff like position cursor, clear screen, colour selection inside the echo string with colours preceded by an '@', random case, colour cylcling and other fun stuff (partly to aid my learning of python and partly for usefulness) - if I wanted to have parts of my class not be a thread how would I do it ? at the moment I have this spinner thing working (whole code here) but I want to call it multiple times. like this:

s=spin()
s.echo('@@') # clears screen
# at the moment - here i get an error because only one thread can be started
s.echo('@red this is red @green green etc...')

the echo function does a lot of stuff as you can see if you look at the pastebin, so i need to call that quite a bit, but multiple calls result in 'only one thread' allowed error. perhaps i should be doing it a different way. This was the basic old code before the pastebin stuff.

spinner="▏▎▍▌▋▊▉█▉▊▌▍▎" #utf8

#convert the utf8 spinner string to a list
chars=[c.encode("utf-8") for c in unicode(spinner,"utf-8")]

class spin(threading.Thread):

    def __init__(self):
        super(spin,self).__init__()
        self._stop = False

    def run (self):
        pos=0
        while not self._stop:
            sys.stdout.write("\r"+chars[pos])
            sys.stdout.flush()
            time.sleep(.15)
            pos+=1
            pos%=len(chars)

    def cursor_visible(self):
        os.system("tput cvvis")
    def cursor_invisible(self):
        os.system("tput civis")
    def stop(self):
        self._stop = True
    def stopped(self):
        return self._stop == True

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2024-12-26 00:39:55

只有 run 方法实际上在不同的线程中运行。您的代码的问题是您尝试多次启动线程(在 echo 方法中)。在启动之前,您应该检查线程是否已经启动(查看 self._stop)。

def echo (self, arg=None, sep=' ', end='\n', rndcase=True, txtspeed=0.03, bnum=0, spsw=True):
    print cursave, 
    self.cursor_invisible()

    # do you have to do all this ? 
    # c0m4: Only if you need all of those to be accessible for the spin object when echo ends
    self.arg=arg
    self.sep=sep
    self.end=end
    self.rndcase=rndcase
    self.txtspeed=txtspeed
    self.bnum=bnum
    self.spsw=spsw

    pos=0
    cmd, txt = [reset], []
    spsw=True
    last_colour=''
    txtpos=0
    if arg:

# test if spinner is wanted and set the text position to be moved across a bit to allow for it
    if spsw is True:
    txtpos=4
    self.start()

最后一行是麻烦开始的地方。不可能多次启动一个线程。因此,在重新启动线程之前,您需要检查线程是否正在运行。添加类似的东西

self.running = False

到你的 init 方法中,然后在 run 方法中设置它

self.running = True

然后你可以检查对象的状态(线程是否运行),如下所示:

if not self.running:
    self.start()

如果你需要运行 run 的初始部分,你应该把它在一个单独的方法中,如下所示:

def resetThread():
    self.pos = 0

Only the run method is actually running in a diffrent thread. The problem with your code is that you try to start the thread more than one time (in the echo method). You should check if the thread is already started (look at self._stop) before starting.

def echo (self, arg=None, sep=' ', end='\n', rndcase=True, txtspeed=0.03, bnum=0, spsw=True):
    print cursave, 
    self.cursor_invisible()

    # do you have to do all this ? 
    # c0m4: Only if you need all of those to be accessible for the spin object when echo ends
    self.arg=arg
    self.sep=sep
    self.end=end
    self.rndcase=rndcase
    self.txtspeed=txtspeed
    self.bnum=bnum
    self.spsw=spsw

    pos=0
    cmd, txt = [reset], []
    spsw=True
    last_colour=''
    txtpos=0
    if arg:

# test if spinner is wanted and set the text position to be moved across a bit to allow for it
    if spsw is True:
    txtpos=4
    self.start()

The last line if where the troubles start. It is not possible to start a thread more then once. Therefore you need to check if the thread is running before you restart it. Add something like

self.running = False

to your init method, and then set it in the run method

self.running = True

Then you can check the status of the object (thread running or not) like this:

if not self.running:
    self.start()

If you need to run the initial portion of run regardless, you should put that in a separate method, like this:

def resetThread():
    self.pos = 0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文