我编写了一个程序,它有一个主线程,它通过对threading.Thread类进行子类化来派生许多其他线程。
每个这样的子线程都运行一个无限的while循环,在循环中我检查一个条件。如果条件为真,我使用time.sleep(1)使线程休眠1秒,如果条件为假,则线程执行一些计算。
程序本身运行良好,我已经实现了我想要做的事情,我唯一剩下的问题是,在我的工作完成后,我似乎无法停止线程。我希望用户能够通过按下一个按钮或像Ctrl+C那样给键盘中断来杀死所有线程。
为此,我尝试使用了signal模块,并在线程的循环中插入了一个条件,当主线程捕获到一个信号时,它会中断循环,但由于某种原因,它不能工作。有人能帮个忙吗?
编辑:这是一些相关的代码片段:
def sighandler(signal,frame):
BaseThreadClass.stop_flag = True
class BaseThreadClass(threading.Thread):
stop_flag = False
def __init__(self):
threading.Thread.__init__(self)
def run(self,*args):
while True:
if condition:
time.sleep(1)
else:
#do computation and stuff
if BaseThreadClass.stop_flag:
#do cleanup
break发布于 2018-06-10 00:56:14
您的基本方法是有效的,但是您仍然没有发布足够的代码来显示该缺陷。我添加了几行代码使其可运行,并产生了如下结果:
$ python3 test.py
thread alive
main alive
thread alive
main alive
^CSignal caught
main alive
thread alive
main alive
main alive
main alive
^CSignal caught
^CSignal caught
main alive
^Z
[2]+ Stopped python3 test.py
$ kill %2上面演示的问题涉及到信号处理程序告诉所有线程退出,除了主线程,它仍然运行并仍然捕获中断。示例代码段的此变体的完整源代码为:
import threading, signal, time
def sighandler(signal,frame):
BaseThreadClass.stop_flag = True
print("Signal caught")
class BaseThreadClass(threading.Thread):
stop_flag = False
def __init__(self):
threading.Thread.__init__(self)
def run(self,*args):
while True:
if True:
time.sleep(1)
print("thread alive")
else:
#do computation and stuff
pass
if BaseThreadClass.stop_flag:
#do cleanup
break
signal.signal(signal.SIGINT, sighandler)
t = BaseThreadClass()
t.start()
while True:
time.sleep(1)
print("main alive")这里的问题是主线程从不检查退出条件。但是,由于您从未发布主线程做了什么,也没有发布信号处理程序是如何激活的,或者关于线程是否会在没有检查退出条件的情况下运行很长时间的信息...我还是不知道你的程序出了什么问题。库文档中显示的signal example会引发异常,以便转移主线程。
然而,对于这个任务来说,信号是一个相当低级的概念。我冒失地写了一个更天真的主线版本:
try:
t = BaseThreadClass()
t.start()
while True:
time.sleep(1)
print("main alive")
except KeyboardInterrupt:
BaseThreadClass.stop_flag = True
t.join()此版本捕获由默认中断处理程序抛出的异常,向线程发出停止信号,并等待线程停止。将except子句更改为finally甚至可能是合适的,因为我们可能还希望清理线程中的其他错误。
发布于 2018-06-10 00:36:18
如果您想要执行这种“协作”轮询关闭,您可以使用threading.Event来发出信号:
import threading
import time
def proc1():
while True:
print("1") # payload
time.sleep(1)
# have we been signalled to stop?
if not ev1.wait(0): break
# do any shutdown etc. here
print ("T1 exiting")
ev1 = threading.Event()
ev1.set()
thread1 = threading.Thread(target=proc1)
thread1.start()
time.sleep(3)
# signal thread1 to stop
ev1.clear()但请注意,如果“有效负载”执行了诸如网络或文件IO之类的阻塞操作,该操作将不会中断。您可以使用超时来执行这些阻塞操作,但这显然会使您的代码变得复杂。
https://stackoverflow.com/questions/50773086
复制相似问题