gpt4 book ai didi

python - 如何在Python中使用队列处理线程中的异常?

转载 作者:行者123 更新时间:2023-12-01 05:05:08 24 4
gpt4 key购买 nike

这永远不会打印:“threadfuncqueue 处理的 threadfuncqueue 中出现异常”,“主线程处理的 threadfuncqueue 中出现异常”和“队列的线程测试已通过”。永不放弃!

from threading import Thread
from Queue import Queue
import time

class ImRaiseError():
def __init__(self):
time.sleep(1)
raise Exception(self.__class__.__name__)

# place for paste worked code example from below

print "begin thread test with queue"
def threadfuncqueue(q):
print "\n"+str(q.get())
while not q.empty():
try:
testthread = ImRaiseError()
finally:
print "Exception in threadfuncqueue handled by threadfuncqueue"

q = Queue()
items = [1,2]
for i in range(len(items)):
t = Thread(target=threadfuncqueue,args=(q,))
if(1 == i):
t.daemon = False
else:
t.daemon = True
t.start()
for item in items:
q.put("threadfuncqueue"+str(item))

try:
q.join() # block until all tasks are done
finally:
print "Exception in threadfuncqueue handled by main thread"
print "thread test with queue passed"
quit()

如何处理这个异常?

工作代码示例,但没有队列:

print "=========== procedure style test"
def threadfunc(q):
print "\n"+str(q)
while True:
try:
testthread = ImRaiseError()
finally:
print str(q)+" handled by process"

try:
threadfunc('testproc')
except Exception as e:
print "error!",e
print "procedure style test ==========="


print "=========== simple thread tests"
testthread = Thread(target=threadfunc,args=('testthread',))
testthread.start()
try:
testthread.join()
finally:
print "Exception in testthread handled by main thread"
testthread1 = Thread(target=threadfunc,args=('testthread1',))
testthread1.start()
try:
testthread1.join()
finally:
print "Exception in testthread1 handled by main thread"
print "simple thread tests ==========="

最佳答案

简短回答

您将事物放入队列中并检索它们,但如果您要加入队列,则需要在将任务从队列中拉出并处理它们时将其标记为已完成。 According to the docs ,每次将一个项目放入队列时,计数器就会递增,并且您需要调用 q.task_done() 来递减该计数器。 q.join() 将阻塞,直到计数器达到零。在 q.get() 调用之后立即添加此内容,以防止 main 被阻塞:

q.task_done()

此外,我发现很奇怪的是,您在从中检索了一些内容后,还要检查 q 是否为空。。我不确定您到底想要实现什么目标,所以我没有任何建议给您,但我建议重新考虑您在该领域的设计。

其他想法

一旦你让这个代码工作起来,你应该把它移交给 Code Review因为它有点乱。这里有一些想法供您引用:

异常处理

您实际上并没有在threadfuncqueue(q)中“处理”异常。 finally 语句所做的只是允许您在发生异常时执行清理代码。它实际上并不捕获和处理异常。异常仍然会沿着调用堆栈向上传播。考虑这个例子,test.py:

try:
raise Exception
finally:
print("Yup!")
print("Nope!")

输出:

Yup!
Traceback (most recent call last):
    File "test.py", line 2, in
        raise Exception
Exception

请注意“是的!”在“不!”的同时被打印出来没有。执行了finally block 中的代码,但这并没有阻止异常在堆栈中传播并停止解释器。为此,您需要 except 语句:

try:
raise Exception
except Exception: # only catch the exceptions you expect
print("Yup!")
print("Nope!")

输出:

Yup!
Nope!

这次两者都被打印,因为我们捕获并处理了异常。

异常引发

您当前在线程中引发异常的方法不必要地复杂。无需创建整个 ImRaiseError 类,只需使用字符串引发所需的异常即可:

raise Exception('Whatever error message I want')

如果您发现自己手动操纵 mangled names (如self.__class__.__name__),你通常做错了什么。

额外的括号

在 Python 中,在条件表达式周围使用括号通常是不受欢迎的:

if(1 == i): # unnecessary extra characters 

尝试打破 C/C++/Java 习惯并摆脱它们:

if 1 == i:

其他

我已经超出了这个问题的范围,所以我现在要结束这个问题,但是还有一些其他的事情你可以清理并变得更惯用。完成此处后,请前往代码审查,看看还有哪些可以改进的地方。

关于python - 如何在Python中使用队列处理线程中的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25200120/

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