Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用键盘中断关闭所有线程_Python_Multithreading - Fatal编程技术网

Python 用键盘中断关闭所有线程

Python 用键盘中断关闭所有线程,python,multithreading,Python,Multithreading,我在这里尝试的是使用键盘中断来退出程序中所有正在进行的线程。这是我创建线程的代码的精简版本: for i in taskDictionary: try: sleep(60) thread = Thread(target = mainModule.executeThread) thread.start() except KeyboardInterrupt: thread.__stop() 程序本身要复杂得多,考虑了影

我在这里尝试的是使用键盘中断来退出程序中所有正在进行的线程。这是我创建线程的代码的精简版本:

for i in taskDictionary:
    try:
        sleep(60)
        thread = Thread(target = mainModule.executeThread)
        thread.start()
    except KeyboardInterrupt:
        thread.__stop()
程序本身要复杂得多,考虑了影响线程的大量不同变量,甚至可以选择以顺序模式启动,其中任务不是线程化的,而是逐个启动的,因此我刚才提出的这个小变化可能会有一些问题。 我这样做的方式产生了50/50的结果。中断可以工作,但线程永远不会干净地退出。有时它们会继续运行,但会停止未来线程的执行,有时它们会退出,并出现与中断有关的大量错误,而其他时候,中断根本不起作用。上次我运行这个程序时,程序停止了任何未来线程的执行,但没有停止当前线程。 有没有办法在不进入线程实际执行的模块的情况下退出线程?

类似的问题是“如何杀死线程?”

您可以在线程中创建一个由线程模块中的锁或事件对象控制的退出处理程序。然后只需移除锁或向事件对象发送信号。这会通知线程它应该停止处理并正常退出。在主程序中向线程发送信号后,唯一要做的就是使用
main
中的
thread.join()
方法,该方法将等待线程关闭

举个简单的例子:

import threading
import time

def timed_output(name, delay, run_event):
    while run_event.is_set():
        time.sleep(delay)
        print name,": New Message!"


def main():
    run_event = threading.Event()
    run_event.set()
    d1 = 1
    t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event))

    d2 = 2
    t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event))

    t1.start()
    time.sleep(.5)
    t2.start()

    try:
        while 1:
            time.sleep(.1)
    except KeyboardInterrupt:
        print "attempting to close threads. Max wait =",max(d1,d2)
        run_event.clear()
        t1.join()
        t2.join()
        print "threads successfully closed"

if __name__ == '__main__':
    main()

如果您确实需要终止线程的功能,请使用多处理。它允许您将SIGTERMs发送到各个“进程”(它也非常类似于线程模块)。一般来说,线程是针对IO绑定的,而多处理是针对真正的处理器绑定的。

有几个选项不需要在线程之间使用锁或其他信号。一种是将线程设置为,当主线程退出时,将自动终止线程。另一种方法是使用,如果需要杀死它们并保持主程序运行,则可以从主进程调用terminate方法

如果有线程阻塞输入,这两种方法都特别有用。虽然使用超时和定期检查信号在大多数情况下都可以正常工作,而不会产生太多开销,但使用守护进程或进程可以消除对任何繁忙循环或显著增加复杂性的需要


有关这些解决方案的更多详细信息以及关于终止线程问题的讨论,请参见的答案。

通过线程的合作,您可以以任何方式终止线程。没有一根线的配合,就没有安全的方法去做,所有的路都会导致痛苦。回答得很好!不完全是我想要的,但是足够广泛,我能够将逻辑调整为我需要的!谢谢你!我使用线程是因为我不想要一个无限while True循环。这会浪费你所有的CPU时间。。。差不多是字面意思。我曾经做过类似的事情,在没有睡眠的情况下,它会一次将CPU%调到100%,持续几秒钟,而在睡眠时间很短的情况下,这只会有一点帮助。有没有什么方法可以不用一段时间就做到这一点呢?@Dylan The infinite loop只是想提供一个精辟的工作示例。通常情况下,人们会在主循环中完成一些主要任务。尽管如此,即使
time.sleep(.001)
也会显著降低cpu负载。在
time.sleep(.010)
我的python线程运行时CPU不足1%。线程应该用于IO绑定的进程或需要定期检查的资源。主循环应该执行您的主代码,如果它需要资源,可能需要50毫秒的睡眠等待。如果处理确实是时间敏感的,您可以始终利用
锁定
协议进行睡眠和唤醒。如果线程在等待I/O时被阻塞,该怎么办?事件是否会以某种方式唤醒它。