我正在尝试查看多线程如何工作以便在自动化项目中使用它们。我可以运行该线程,但我找不到完全退出两个线程的方法:每个键盘中断后线程重启。有没有办法用键盘中断退出两个线程?
import thread
from time import sleep
*parameters when starting
temp_c = 32
T_hot = 30
T_cold = 27
interval_temp = 2
def ctrl_fan(temp_c, T_hot,interval_temp):
while True:
if temp_c >= T_hot:
print 'refreshing'
else:
print ' fan stopped'
sleep(interval_temp)
print 'shutting everything off'
def ctrl_light(temp_c, T_cold,interval_temp):
while True:
if temp_c <= T_cold:
print 'warming'
else:
print 'light stopped'
sleep(interval_temp)
print 'shutting everything off'
try:
thread.start_new_thread(ctrl_fan, (temp_c, T_hot,interval_temp, ) )
sleep(1)
thread.start_new_thread(ctrl_light, (temp_c, T_cold,interval_temp, ) )
except (KeyboardInterrupt, SystemExit):
thread.exit()
print "Error: unable to start thread"
答案 0 :(得分:1)
当然,
首先,我建议使用略高一级的threading
模块而不是thread
模块。
要使用threading
启动帖子,请使用以下
import threading
t = threading.Thread(target=ctrl_fan, args=(temp_c, T_hot, interval_temp))
t.start()
要让程序以Ctrl-C
中断退出,您需要执行一些操作。
首先,您需要将线程设置为daemon,以便它们允许程序在主线程退出时退出(t.daemon = True
)
您还希望主线程在线程完成时等待,您可以使用t.join()
来完成此操作。但是,在线程完成之前,这不会引发KeyboardInterrupt
异常,但是有一个解决方法,但
while t.is_alive():
t.join(1)
提供超时值可以解决这个问题。
我很想将它们整合到一个子类中,以获得你想要的行为
import threading
class CustomThread(threading.Thread):
def __init__(self, *args, **kwargs):
threading.Thread.__init__(self, *args, **kwargs)
self.daemon = True
def join(self, timeout=None):
if timeout is None:
while self.is_alive():
threading.Thread.join(self, 10)
else:
return threading.Thread.join(self, timeout)
t1 = CustomThread(target=ctrl_fan, args=(temp_c, T_hot, interval_temp))
t1.start()
t2 = CustomThread(target=ctrl_light, args=(temp_c, T_cold, interval_temp))
t2.start()
t1.join()
t2.join()
答案 1 :(得分:1)
再次,在文档(https://docs.python.org/2/library/thread.html)中解释:
线程与中断奇怪地交互:KeyboardInterrupt异常将由任意线程接收。 (当信号模块可用时,中断始终转到主线程。)
您肯定会在https://stackoverflow.com/中找到答案,例如: