使用threading.Event()时我遇到了一个非常奇怪的问题,并且无法理解发生了什么?我一定错过了什么,请你指出来吗?
我有一个Listener类,它与信号处理程序共享相同的事件对象,这是我的简化代码:
import threading, time
class Listener(object):
def __init__(self, event):
super(Listener, self).__init__()
self.event = event
def start(self):
while not self.event.is_set():
print("Listener started, waiting for messages ...")
self.event.wait()
print("Listener is terminated ...")
self.event.clear()
event = threading.Event()
def handler(signum, frame):
global event
event.set()
print('Signal handler called with signal [%s]' % signum)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
listener = Listener(event)
listener.start()
运行代码后,按ctrl + c中断它,实际上什么也没发生。如果我想退出,我必须使用kill -9来杀死进程。但是,如果我向event.wait()
提供一个参数,它就可以了。但它一直打印出来:
听众启动,等待消息......"
每次都是秒。但它会打印出来:
听众被终止......
按Ctrl + c这就是我想要的。
while not self.event.is_set():
print("Listener started, waiting for messages ...")
self.event.wait(1)
为什么我必须在event.wait()
中给出超时参数以使其响应ctrl + c事件?根据文档http://docs.python.org/2/library/threading.html#event-objects,一旦标志为真,调用wait()
的event.wait()线程将不会阻塞。我顺便使用python 2.7.3。
答案 0 :(得分:2)
这对你有用吗?基本上,为Listener启动另一个线程,并在主线程等待信号时等待。
#!/usr/bin/python
import threading, signal
class Listener(threading.Thread):
def __init__(self, event):
super(Listener, self).__init__()
self.event = event
def run(self):
while not self.event.is_set():
print("Listener started, waiting for messages ...")
self.event.wait()
print("Listener is terminated ...")
self.event.clear()
event = threading.Event()
def handler(signum, frame):
global event
event.set()
print('Signal handler called with signal [%s]' % signum)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
listener = Listener(event)
listener.start()
while listener.is_alive():
pass
答案 1 :(得分:1)
答案 2 :(得分:0)
以下代码与原始代码类似。
的差异:
继承Thread
类,使用run
(vs start)
使用简单的wait()
,没有超时,这是更可预测的
信号处理程序不会直接触发Event
。相反,它只是隐含地唤醒了主要流程,该流程位于signal.pause()
。
主要触发器Event.set()
从pause()
唤醒后触发SIGINT
- 主过程将在任何信号上执行此操作,而不只是import signal, threading, time
class Listener(threading.Thread):
def __init__(self, event):
super(Listener, self).__init__()
self.event = event
def run(self):
print("Listener started, waiting for messages ...")
while not self.event.wait():
print('(timeout)')
print("Listener is terminated ...")
self.event.clear()
event = threading.Event()
def handler(signum, _frame):
# global event
# event.set()
print('Signal handler called with signal [%s]' % signum)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGALRM, handler)
signal.alarm(2)
listener = Listener(event)
listener.start()
print '* PAUSE'
signal.pause() # wait for a signal
print '* SIGNALLING'
event.set()
listener.join()
print('* DONE')
(控制-C)。出于测试目的,两秒钟后会有一个报警电话。
希望这有帮助!
Listener started, waiting for messages ...
* PAUSE
Signal handler called with signal [14]
* SIGNALLING
Listener is terminated ...
* DONE
{{1}}