我正在进行一个涉及数据收集和日志记录的项目。我有两个线程在运行,一个是收集线程,另一个是日志线程,两者都在主线程中启动。我试图允许程序在按下Ctrl-C时优雅地终止。
我使用了
我不明白为什么第二个线程永远不会终止。我基于这个答案做的:Stopping a thread after a certain amount of time。我错过了什么吗?
我使用了
threading.Event
来向线程发出结束它们各自循环的信号。它可以正常停止sim_collectData
方法,但似乎不能正确地停止logData
线程。"Collection terminated"打印语句从未被执行,程序就会僵死。(它不会结束,只是坐在那里)。
logData
中的第二个while
循环是为了确保队列中的所有内容都被记录下来。目标是让Ctrl-C立即停止收集线程,然后允许日志线程完成清空队列的工作,然后才完全终止程序。(现在,数据只是被打印出来 - 最终将被记录到数据库中)。我不明白为什么第二个线程永远不会终止。我基于这个答案做的:Stopping a thread after a certain amount of time。我错过了什么吗?
def sim_collectData(input_queue, stop_event):
''' this provides some output simulating the serial
data from the data logging hardware.
'''
n = 0
while not stop_event.is_set():
input_queue.put("DATA: <here are some random data> " + str(n))
stop_event.wait(random.randint(0,5))
n += 1
print "Terminating data collection..."
return
def logData(input_queue, stop_event):
n = 0
# we *don't* want to loop based on queue size because the queue could
# theoretically be empty while waiting on some data.
while not stop_event.is_set():
d = input_queue.get()
if d.startswith("DATA:"):
print d
input_queue.task_done()
n += 1
# if the stop event is recieved and the previous loop terminates,
# finish logging the rest of the items in the queue.
print "Collection terminated. Logging remaining data to database..."
while not input_queue.empty():
d = input_queue.get()
if d.startswith("DATA:"):
print d
input_queue.task_done()
n += 1
return
def main():
input_queue = Queue.Queue()
stop_event = threading.Event() # used to signal termination to the threads
print "Starting data collection thread...",
collection_thread = threading.Thread(target=sim_collectData, args=(input_queue, stop_event))
collection_thread.start()
print "Done."
print "Starting logging thread...",
logging_thread = threading.Thread(target=logData, args=(input_queue, stop_event))
logging_thread.start()
print "Done."
try:
while True:
time.sleep(10)
except (KeyboardInterrupt, SystemExit):
# stop data collection. Let the logging thread finish logging everything in the queue
stop_event.set()
main()
input_queue.get()
添加超时。 - Jan