4

我正在尝试python中的线程。我希望在另一个方法运行时显示一个旋转光标(5-10 分钟)。我已经完成了一些代码,但我想知道你会这样做吗?我不喜欢使用全局变量,所以我认为有更好的方法吗?

c = True 

def b():
    for j in itertools.cycle('/-\|'):
        if (c == True):
            sys.stdout.write(j)
            sys.stdout.flush()
            time.sleep(0.1)
            sys.stdout.write('\b')
        else:
            return

def a():
    global c
    #code does stuff here for 5-10 minutes
    #simulate with sleep
    time.sleep(2)
    c = False

Thread(target = a).start()
Thread(target = b).start()

编辑:

现在的另一个问题是,当处理结束时,旋转光标的最后一个元素仍在屏幕上。所以\打印了类似的东西。

4

3 回答 3

3

您可以使用事件: http ://docs.python.org/2/library/threading.html

我对此进行了测试,并且可以正常工作。它还使一切保持同步。您应该避免在不同步它们的情况下更改/读取不同线程中的相同变量。

#!/usr/bin/python

from threading import Thread
from threading import Event
import time
import itertools
import sys

def b(event):
    for j in itertools.cycle('/-\|'):
        if not event.is_set():
            sys.stdout.write(j)
            sys.stdout.flush()
            time.sleep(0.1)
            sys.stdout.write('\b')
        else:
            return

def a(event):
    #code does stuff here for 5-10 minutes
    #simulate with sleep
    time.sleep(2)
    event.set()

def main():
    c = Event()
    Thread(target = a, kwargs = {'event': c}).start()
    Thread(target = b, kwargs = {'event': c}).start()

if __name__ == "__main__":
    main()

与“kwargs”相关,来自 Python 文档(文章开头的 URL):

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
...
    kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.
于 2013-05-13T09:14:24.017 回答
3

除了全局变量外,您大部分时间都在正确的轨道上。通常,您需要使用锁或信号量来协调对共享数据的访问,但在这种特殊情况下,您可以采取捷径,只使用其中一个线程是否正在运行。这就是我的意思:

from threading import Thread
from threading import Event
import time
import itertools
import sys

def monitor_thread(watched_thread):
    chars = itertools.cycle('/-\|')
    while watched_thread.is_alive():
        sys.stdout.write(chars.next())
        sys.stdout.flush()
        time.sleep(0.1)
        sys.stdout.write('\b')

def worker_thread():
    # code does stuff here - simulated with sleep
    time.sleep(2)

if __name__ == "__main__":
    watched_thread = Thread(target=worker_thread)
    watched_thread.start()
    Thread(target=monitor_thread, args=(watched_thread,)).start()
于 2013-05-13T10:40:46.617 回答
1

这未正确同步。但我现在不会试图向你解释这一切,因为它涉及大量知识。尝试阅读:http ://effbot.org/zone/thread-synchronization.htm

但在你的情况下,事情没有同步正确并不是那么糟糕。唯一可能发生的情况是,旋转条的旋转时间比后台任务实际需要的时间长几毫秒。

于 2013-05-13T09:09:15.033 回答