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

时间:2011-11-30 19:07:59

标签: python multithreading class

昨天我已经问了一个关于this的问题,但是现在我还有另外一个:)我试图为我的终端应用程序编写一个文本效果类型类 - 它确实像位置光标,清晰的屏幕,颜色在echo字符串中选择颜色前面带有'@',随机情况,颜色循环和其他有趣的东西(部分是为了帮助我学习python,部分是为了实用性) - 如果我想让我的类的部分不是一个线程我该怎么办?目前我有这个微调器工作(整个代码here),但我想多次调用它。像这样:

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

1 个答案:

答案 0 :(得分:0)

只有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()

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

def resetThread():
    self.pos = 0