gpt4 book ai didi

python - 即使在 KeyboardInterrupt 之后,多线程代码仍会继续打印

转载 作者:太空宇宙 更新时间:2023-11-04 03:11:12 25 4
gpt4 key购买 nike

我有一个非常简单的多线程 python 代码,其中有两个线程试图从队列中弹出和打印。我使用锁来确保互斥。一切正常,除了:

  1. 如果我导入 python 的内置 Queue,程序会在终端的 KeyboardInterrup 上退出
  2. 如果我定义自定义 class Queue(object)(在内部实现为 list),即使在 KeyboardInterrupt< 之后,线程也会继续打印到终端

这是我的代码:https://ideone.com/ArTcwE (虽然你不能在ideone上测试KeyboardInterrupt)

PS:我已经经历了Close multi threaded application with KeyboardInterrupt已经。它没有解决我的问题。

更新 1:我理解(感谢@SuperSaiyan 的回答)为什么线程会在场景 # 2 中继续工作——主函数在 job_done 可以设置之前就死了为 True。因此,线程一直在等待信号到达。但奇怪的是,即使在场景 # 1 中,job_done 仍然是 False。线程以某种方式被杀死:

>>> execfile('threaded_queue.py')
Starting Q1Starting Q2

Q1 got 0
Q2 got 1
Q1 got 2
Q1 got 3


Traceback (most recent call last):
File "<pyshell#68>", line 1, in <module>
execfile('threaded_queue.py')
File "threaded_queue.py", line 54, in <module>
while not q.empty():
KeyboardInterrupt
>>> job_done
False
>>>

更新 2:将代码粘贴到此处以实现永久性:

from time import time, ctime, sleep
from threading import Thread, Lock
from Queue import Queue

class MyQueue(object):
def __init__(self):
self.store = []

def put(self, value):
self.store.append(value)

def get(self):
return self.store.pop(0)

def empty(self):
return not self.store


class SyncQueue(Thread):
__lock = Lock()

def __init__(self, name, delay, queue):
Thread.__init__(self)
self.name = name
self.delay = delay
self.queue = queue

def run(self):
print "Starting %s" % self.name
while not self.queue.empty():
with self.__lock:
print "%s got %s" % (
self.name,
self.queue.get())
sleep(self.delay)
while not job_done:
sleep(self.delay)
print "Exiting %s" % self.name

if __name__ == "__main__":
job_done = False
#q = Queue(5) # Python's Queue
q = MyQueue() # Custom Queue
for i in xrange(5):
q.put(i)
q1 = SyncQueue("Q1", .5, q)
q2 = SyncQueue("Q2", 1, q)
q1.start()
q2.start()

# Wait for the job to be done
while not q.empty():
pass
job_done = True
q1.join()
q2.join()
print "All done!"

最佳答案

您的问题不是您的自定义 Queue 与 python 的 Queue。这完全是另一回事。此外,即使使用 python 的 Queue 实现,您也会看到相同的行为。

这是因为当您按下 ctrl+C 时您的主线程在它能够向其他两个线程发出退出信号之前终止(使用 job_done = True)。

您需要的是一种告诉其他两个线程退出的机制。下面是一个简单的机制——您可能需要更强大的东西,但您会明白的:

try:
while not job_done:
time.sleep(0.1) #Trying using this instead of CPU intensive `pass`.
except KeyboardInterrupt as e:
job_done = True

关于python - 即使在 KeyboardInterrupt 之后,多线程代码仍会继续打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37960126/

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