终止多线程python程序 [英] Terminate a multi-thread python program

查看:314
本文介绍了终止多线程python程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何对Ctrl + C键事件做出多线程python程序响应?

How to make a multi-thread python program response to Ctrl+C key event?

代码如下:

import threading
current = 0

class MyThread(threading.Thread):
    def __init__(self, total):
        threading.Thread.__init__(self)
        self.total = total

    def stop(self):
        self._Thread__stop()

    def run(self):
        global current
        while current<self.total:
            lock = threading.Lock()
            lock.acquire()
            current+=1
            lock.release()
            print current

if __name__=='__main__':

    threads = []
    thread_count = 10
    total = 10000
    for i in range(0, thread_count):
        t = MyThread(total)
        t.setDaemon(True)
        threads.append(t)
    for i in range(0, thread_count):
        threads[i].start()

我试图在所有线程上删除join(),但仍然无法正常工作.是因为每个线程的run()过程中的锁段是什么?

I tried to remove join() on all threads but it still doesn't work. Is it because the lock segment inside each thread's run() procedure?

该代码本来可以工作,但是当当前变量在5,000-6,000范围内并出现以下错误时,它始终会中断

The above code is supposed to work but it always interrupted when current variable was in 5,000-6,000 range and through out the errors as below

Exception in thread Thread-4 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
  File "/usr/lib/python2.5/threading.py", line 486, in __bootstrap_inner
  File "test.py", line 20, in run
<type 'exceptions.TypeError'>: unsupported operand type(s) for +=: 'NoneType' and 'int'
Exception in thread Thread-2 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
  File "/usr/lib/python2.5/threading.py", line 486, in __bootstrap_inner
  File "test.py", line 22, in run

推荐答案

使除主线程之外的每个线程都成为守护进程(对于每个线程对象tt.daemon = True在2.6或更高版本中,t.setDaemon(True)在2.6或更低版本中)在您开始之前).这样,当主线程收到KeyboardInterrupt时,如果它没有捕获到或捕获到它,但是无论如何决定终止,则整个过程将终止.请参见文档.

Make every thread except the main one a daemon (t.daemon = True in 2.6 or better, t.setDaemon(True) in 2.6 or less, for every thread object t before you start it). That way, when the main thread receives the KeyboardInterrupt, if it doesn't catch it or catches it but decided to terminate anyway, the whole process will terminate. See the docs.

编辑:刚刚看过OP的代码(最初未发布),并声称它不起作用",看来我必须添加...:

edit: having just seen the OP's code (not originally posted) and the claim that "it doesn't work", it appears I have to add...:

当然,如果您希望主线程保持响应(例如,对Control-C的响应),请不要将其陷入阻塞调用中,例如join另一个线程-特别是不要完全 useless 阻止调用,例如join ing daemon 线程.例如,只需更改当前线程在主线程中的最终循环(完全无损):

Of course, if you want your main thread to stay responsive (e.g. to control-C), don't mire it into blocking calls, such as joining another thread -- especially not totally useless blocking calls, such as joining daemon threads. For example, just change the final loop in the main thread from the current (utterless and damaging):

for i in range(0, thread_count):
    threads[i].join()

更明智的选择:

while threading.active_count() > 0:
    time.sleep(0.1)

如果主线程除了要使所有线程自己终止,或者要接收到Control-C(或其他信号)之外,没有比这更好的事情了.

if your main has nothing better to do than either for all threads to terminate on their own, or for a control-C (or other signal) to be received.

当然,如果您不希望线程突然终止(如守护线程可能),还有许多其他可用模式-除非它们也永远陷入无条件阻塞中呼叫,死锁等;-).

Of course, there are many other usable patterns if you'd rather have your threads not terminate abruptly (as daemonic threads may) -- unless they, too, are mired forever in unconditionally-blocking calls, deadlocks, and the like;-).

这篇关于终止多线程python程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆