这是一些精简的代码,演示了我对线程的使用:
import threading
import Queue
import time
def example():
""" used in MainThread as the example generator """
while True:
yield 'asd'
class ThreadSpace:
""" A namespace to be shared among threads/functions """
# set this to True to kill the threads
exit_flag = False
class MainThread(threading.Thread):
def __init__(self, output):
super(MainThread, self).__init__()
self.output = output
def run(self):
# this is a generator that contains a While True
for blah in example():
self.output.put(blah)
if ThreadSpace.exit_flag:
break
time.sleep(0.1)
class LoggerThread(threading.Thread):
def __init__(self, output):
super(LoggerThread, self).__init__()
self.output = output
def run(self):
while True:
data = self.output.get()
print data
def main():
# start the logging thread
logging_queue = Queue.Queue()
logging_thread = LoggerThread(logging_queue)
logging_thread.daemon = True
logging_thread.start()
# launch the main thread
main_thread = MainThread(logging_queue)
main_thread.start()
try:
while main_thread.isAlive():
time.sleep(0.5)
except KeyboardInterrupt:
ThreadSpace.exit_flag = True
if __name__ == '__main__':
main()
我有一个主线程,它从阻塞生成器获取数据。在实际代码中,此生成器会生成它通过套接字嗅出的与网络相关的数据。
然后我有一个日志记录、守护进程、线程,它将数据打印到屏幕上。
为了干净地退出程序,我正在捕获一个KeyboardInterrupt
将设置一个exit_flag
尝试的 - 这告诉主线程返回。
10 次中有 9 次,这将正常工作。程序将干净地退出。但是,有时我会收到以下两个错误:
错误一:
^CTraceback (most recent call last):
File "demo.py", line 92, in <module>
main('')
File "demo.py", line 87, in main
time.sleep(0.5)
KeyboardInterrupt
错误2:
Exception KeyboardInterrupt in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored
我已经多次运行这个确切的示例代码,但无法复制错误。此代码与真实代码之间的唯一区别是example()
生成器。就像我说的,这会从套接字产生网络数据。
你能看出我处理线程的方式有什么问题吗?