25

我计划在线程中运行一个很长的过程,否则它将冻结我的 wxpython 应用程序中的 UI。

我在用着:

threading.Thread(target=myLongProcess).start()

启动线程并且它可以工作,但我不知道如何暂停和恢复线程。我在 Python 文档中查找了上述方法,但找不到它们。

谁能建议我怎么做?

4

6 回答 6

21

我也做了一些速度测试,在一个慢速的 2 处理器 Linux 机器上,设置标志和采取行动的时间快得令人愉快 0.00002 秒。

set()使用和clear()事件的线程暂停测试示例:

import threading
import time

# This function gets called by our thread.. so it basically becomes the thread init...                
def wait_for_event(e):
    while True:
        print('\tTHREAD: This is the thread speaking, we are Waiting for event to start..')
        event_is_set = e.wait()
        print('\tTHREAD:  WHOOOOOO HOOOO WE GOT A SIGNAL  : %s' % event_is_set)
        # or for Python >= 3.6
        # print(f'\tTHREAD:  WHOOOOOO HOOOO WE GOT A SIGNAL  : {event_is_set}')
        e.clear()

# Main code
e = threading.Event()
t = threading.Thread(name='pausable_thread', 
                     target=wait_for_event,
                     args=(e,))
t.start()

while True:
    print('MAIN LOOP: still in the main loop..')
    time.sleep(4)
    print('MAIN LOOP: I just set the flag..')
    e.set()
    print('MAIN LOOP: now Im gonna do some processing')
    time.sleep(4)
    print('MAIN LOOP:  .. some more processing im doing   yeahhhh')
    time.sleep(4)
    print('MAIN LOOP: ok ready, soon we will repeat the loop..')
    time.sleep(2)
于 2013-02-11T00:33:27.873 回答
9

没有其他线程强制暂停线程的方法(就像其他线程杀死该线程一样)-目标线程必须通过偶尔检查适当的“标志”来合作(athreading.Condition可能适合暂停/取消暂停案子)。

如果您在 unix-y 平台上(基本上除了 windows 之外的任何平台),您可以使用multiprocessing--threading强大,并让您向“其他进程”发送信号;SIGSTOP应该无条件地暂停一个进程并SIGCONT继续它(如果您的进程需要在它暂停之前立即做某事,还要考虑SIGTSTP信号,其他进程可以捕获该信号以执行此类预暂停职责。(可能有一些方法可以获得在 Windows 上具有相同的效果,但我不了解它们(如果有的话)。

于 2010-07-16T06:27:30.370 回答
3

您可以使用信号:http ://docs.python.org/library/signal.html#signal.pause

为避免使用信号,您可以使用令牌传递系统。如果您想从主 UI 线程暂停它,您可能只需使用 Queue.Queue 对象与其通信。

只需弹出一条消息,告诉线程休眠一段时间到队列中。

或者,您可以简单地将令牌从主 UI 线程连续推送到队列中。工作人员应该每 N 秒(0.2 或类似的时间)检查一次队列。当没有令牌出队时,工作线程将阻塞。当您希望它重新开始时,只需再次开始将令牌从主线程推送到队列中。

于 2010-07-16T06:22:01.140 回答
2

多处理模块在 Windows 上运行良好。请参阅此处的文档(第一段结尾):

http://docs.python.org/library/multiprocessing.html

在 wxPython IRC 频道上,我们有几个人尝试了多处理,他们说它有效。不幸的是,我还没有看到有人编写了多处理和 wxPython 的好例子。

如果您(或这里的任何其他人)想出一些东西,请将其添加到 wxPython wiki 页面上的线程:http ://wiki.wxpython.org/LongRunningTasks

您可能想要检查该页面,因为它有几个使用线程和队列的有趣示例。

于 2010-07-16T15:18:50.613 回答
1

您可以查看用于线程暂停的 Windows API

据我所知,没有 POSIX/pthread 等价物。此外,我无法确定Python 是否提供了线程句柄/ID 。Python 也存在潜在问题,因为它的调度是使用本机调度程序完成的,它不太可能期望线程挂起,特别是如果线程在持有 GIL 时挂起,以及其他可能性。

于 2010-07-16T07:21:36.270 回答
1

我遇到过同样的问题。在线程循环中使用 time.sleep(1800) 来暂停线程执行更有效。

例如

MON, TUE, WED, THU, FRI, SAT, SUN = range(7) #Enumerate days of the week
Thread 1 : 
def run(self):
        while not self.exit:
            try:
                localtime = time.localtime(time.time())
                #Evaluate stock
                if localtime.tm_hour > 16 or localtime.tm_wday > FRI:
                    # do something
                    pass
                else:
                    print('Waiting to evaluate stocks...')
                    time.sleep(1800)
            except:
                print(traceback.format_exc())

Thread 2
def run(self):
    while not self.exit:
        try:
            localtime = time.localtime(time.time())
            if localtime.tm_hour >= 9 and localtime.tm_hour <= 16:
                # do something
                pass
            else:
                print('Waiting to update stocks indicators...')
                time.sleep(1800)
        except:
            print(traceback.format_exc())
于 2020-01-11T19:58:42.507 回答