如何在Python中处理队列线程中的异常?

如何在Python中处理队列线程中的异常?,python,multithreading,queue,Python,Multithreading,Queue,这永远不会被打印出来: “threadfuncqueue中的异常由threadfuncqueue处理”, “线程队列中的异常由主线程处理”和 “通过队列的线程测试”。永不放弃 from threading import Thread from Queue import Queue import time class ImRaiseError(): def __init__(self): time.sleep(1) raise Exception(self

这永远不会被打印出来: “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 ==========="
简短回答 您正在将内容放入队列并检索它们,但如果您要加入队列,则需要在将任务从队列中拉出并进行处理时将任务标记为已完成,每次您将一个项目排队时,计数器都会递增,您需要调用
q.task_done()
来递减该计数器
q.join()
将阻塞,直到计数器达到零。在调用
q.get()
后立即添加此命令,以防止main被阻塞:

q.task_done()
另外,我觉得奇怪的是,当你从
q
中检索到一些东西后,你会检查它是否为空。我不确定你到底想用它实现什么,所以我没有任何建议给你,但我建议重新考虑你在这方面的设计

其他想法 一旦你得到了这段代码,你应该把它交给你,因为它有点乱。以下是一些想法:

异常处理 实际上,您并没有在
threadfuncqueue(q)
中“处理”异常。所有
finally
语句都允许您在发生异常时执行清理代码。它实际上并没有捕获和处理异常。异常仍将沿调用堆栈向上移动。考虑这个例子,Test.Py:

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

是的
回溯(最近一次呼叫最后一次):
文件“test.py”,第2行,在
引发异常
例外情况

注意,“是的!”被打印出来,而“不!”没有。执行了
finally
块中的代码,但这并没有阻止异常向堆栈上传播并停止解释器。您需要
语句,但
语句除外:

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

是的

这一次两个都被打印出来,因为我们捕获并处理了异常

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

raise Exception('Whatever error message I want')
如果你发现自己在手动操作(比如
self.\uuuuuuu class.\uuuuuu.\uuuuuu name.\uuuuuuuuuu
),你通常会做错事

附加括号 在Python中,通常不赞成在条件表达式周围使用括号:

if(1 == i): # unnecessary extra characters 
尝试打破C/C++/Java的习惯并摆脱它们:

if 1 == i:
其他 我已经超出了这个问题的范围,所以我现在要把它删掉,但是还有一些事情你可以清理一下,让它更地道。完成这里的工作后,请转到代码复查,看看还有哪些地方可以改进