Python 调用Event.set()后不会通知threading.Event().wait()
我在使用threading.Event()时遇到了一个非常奇怪的问题,无法理解发生了什么?我一定错过了什么,请你指出一下好吗 我有一个侦听器类,它与信号处理程序共享同一个事件对象,下面是我的简化代码:Python 调用Event.set()后不会通知threading.Event().wait(),python,python-multithreading,Python,Python Multithreading,我在使用threading.Event()时遇到了一个非常奇怪的问题,无法理解发生了什么?我一定错过了什么,请你指出一下好吗 我有一个侦听器类,它与信号处理程序共享同一个事件对象,下面是我的简化代码: import threading, time class Listener(object): def __init__(self, event): super(Listener, self).__init__() self.eve
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终止进程。但是,如果我向事件.wait()
提供一个参数,它就起作用了。但它一直在打印:
侦听器已启动,正在等待消息…”
每次都是秒。但它会打印出来:
侦听器已终止
按Ctrl+c键,这就是我想要的
while not self.event.is_set():
print("Listener started, waiting for messages ...")
self.event.wait(1)
为什么我必须在
event.wait()
中提供一个timeout参数才能使其响应ctrl+c事件?根据文档,调用wait()的event.wait()线程
一旦标志为true,就不会阻塞。顺便说一句,我正在使用python 2.7.3。有几个线程讨论python线程、中断、锁和事件的相关问题
例如,请参见和,但还有更多
python3的情况要好得多,它改进了
wait()
的实现,使其不可中断。这对您有用吗?基本上,为侦听器启动另一个线程,在主线程等待信号时在那里等待
#!/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
以下代码与原始代码类似 差异:
线程
类,使用运行
(vs开始)wait()
,这更容易预测事件
。相反,它只是隐式地唤醒主进程,该进程位于signal.pause()
pause()
唤醒后触发Event.set()
——主程序将在任何信号上执行此操作,而不仅仅是SIGINT
(control-C)。出于测试目的,两秒钟后会有报警呼叫这个链接可能会帮助您-。基本上,它解释了信号是由解释器处理的,而
event.wait()
由C函数执行。所以解释器只需等待C函数退出,除非您指定超时,否则不会发生。感谢您指出这一点。这很有帮助。非常感谢Rumple,这确实有效。但单独运行线程可能并不理想。我将只使用self.event.wait(1)但是再次感谢你的帮助。
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')
Listener started, waiting for messages ...
* PAUSE
Signal handler called with signal [14]
* SIGNALLING
Listener is terminated ...
* DONE