gpt4 book ai didi

python - 如何让 Python 线程优雅地完成

转载 作者:行者123 更新时间:2023-12-04 14:02:04 26 4
gpt4 key购买 nike

我正在做一个涉及数据收集和记录的项目。我有 2 个线程正在运行,一个收集线程和一个日志记录线程,它们都在主线程中启动。我试图让程序在使用 Ctrl-C 时优雅地终止。

我正在使用 threading.Event向线程发出信号以结束它们各自的循环。停止 sim_collectData 工作正常方法,但它似乎没有正确停止 logData线。 Collection terminated print 语句永远不会执行,程序只是停止。 (它没有结束,只是坐在那里)。

第二个whilelogData 中循环是确保队列中的所有内容都被记录。目标是让 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()

最佳答案

问题是您的记录器正在等待 d = input_queue.get()并且不会检查事件。一种解决方案是完全跳过该事件并发明一个独特的消息来告诉记录器停止。当您收到信号时,将该消息发送到队列。

import threading
import Queue
import random
import 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..."
input_queue.put(None)
return

def logData(input_queue):
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 True:
d = input_queue.get()
if d is None:
input_queue.task_done()
return
if d.startswith("DATA:"):
print d
input_queue.task_done()
n += 1

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,))
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()

关于python - 如何让 Python 线程优雅地完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17554046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com