线程 Thread-1 中的 Python 异常(最有可能在解释器关闭期间引发)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20596918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Exception in thread Thread-1 (most likely raised during interpreter shutdown)?
提问by Nick Jarvis
My friend and I have been working on a large project to learn and for fun in python and PyGame. Basically it is an AI simulation of a small village. we wanted a day/night cycle so I found a neat way to change the color of an entire surface using numpy (specifically the cross-fade tutorial) - http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro.html
我和我的朋友一直致力于一个大型项目,以学习 Python 和 PyGame 并从中获得乐趣。基本上它是一个小村庄的人工智能模拟。我们想要一个日/夜循环,所以我找到了一种使用 numpy(特别是交叉淡入淡出教程)改变整个表面颜色的巧妙方法 - http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro。 html
I implemented it into the code and it WORKS, but is extremely slow, like < 1 fps slow. so I look into threading (because I wanted to add it eventually) and found this page on Queues - Learning about Queue module in python (how to run it)
我在代码中实现了它并且它可以工作,但是非常慢,比如 < 1 fps 慢。所以我研究了线程(因为我最终想添加它)并在 Queues - Learning about Queue module in python(如何运行它)上找到了这个页面
I spend about 15 minutes making a basic system but as soon as I run it, the window closes and it says
我花了大约 15 分钟来制作一个基本系统,但是一旦我运行它,窗口就会关闭并显示
Exception in thread Thread-1 (most likely raised during interpreter shutdown):
EDIT: This is literally all it says, no Traceback error
编辑:这就是它所说的全部,没有回溯错误
I don't know what I am doing wrong, but I assume I am missing something simple. I added the necessary parts of the code below.
我不知道我做错了什么,但我认为我错过了一些简单的东西。我在下面的代码中添加了必要的部分。
q_in = Queue.Queue(maxsize=0)
q_out = Queue.Queue(maxsize=0)
def run(): #Here is where the main stuff happens
#There is more here I am just showing the essential parts
while True:
a = abs(abs(world.degree-180)-180)/400.
#Process world
world.process(time_passed_seconds)
blank_surface = pygame.Surface(SCREEN_SIZE)
world.render(blank_surface) #The world class renders everything onto a blank surface
q_in.put((blank_surface, a))
screen.blit(q_out.get(), (0,0))
def DayNight():
while True:
blank_surface, a = q_in.get()
imgarray = surfarray.array3d(blank_surface) # Here is where the new numpy stuff starts (AKA Day/Night cycle)
src = N.array(imgarray)
dest = N.zeros(imgarray.shape)
dest[:] = 20, 30, 120
diff = (dest - src) * a
xfade = src + diff.astype(N.int)
surfarray.blit_array(blank_surface, xfade)
q_out.put(blank_surface)
q_in.task_done()
def main():
MainT = threading.Thread(target=run)
MainT.daemon = True
MainT.start()
DN = threading.Thread(target=DayNight)
DN.daemon = True
DN.start()
q_in.join()
q_out.join()
If anyone could help it would be greatly appreciated. Thank you.
如果有人可以提供帮助,将不胜感激。谢谢你。
采纳答案by Tim Peters
This is pretty common when using daemon threads. Why are you setting .daemon = Trueon your threads? Think about it. While there are legitimate uses for daemon threads, mosttimes a programmer does it because they're confused, as in "I don't know how to shut my threads down cleanly, and the program will freeze on exit if I don't, so I know! I'll say they're daemon threads. Then the interpreter won't wait for them to terminate when it exits. Problem solved."
这在使用守护线程时很常见。你为什么.daemon = True在你的线程上设置?想想看。虽然守护线程有合法用途,但大多数时候程序员这样做是因为他们感到困惑,例如“我不知道如何干净地关闭我的线程,如果我不这样做,程序将在退出时冻结,所以我知道!我会说它们是守护线程。然后解释器在退出时不会等待它们终止。问题解决了。”
But it isn't solved - it usually just creates other problems. In particular, the daemon threads keep on running while the interpreter is - on exit - destroying itself. Modules are destroyed, stdin and stdout and stderr are destroyed, etc etc. All sorts of things can go wrong in daemon threads then, as the stuff they try to access is annihilated.
但这并没有解决——它通常只会造成其他问题。特别是,当解释器退出时,守护线程继续运行 - 正在销毁自己。模块被销毁,stdin 和 stdout 以及 stderr 被销毁等等。然后在守护线程中各种事情都可能出错,因为他们试图访问的东西被消灭了。
The specific message you're seeing is produced when an exception is raised in some thread, but interpreter destruction has gotten so far that even the sysmodule no longer contains anything usable. The threading implementation retains a reference to sys.stderrinternally so that it can tell you somethingthen (specifically, the exact message you're seeing), but too much of the interpreter has been destroyed to tell you anything else about what went wrong.
您看到的特定消息是在某个线程中引发异常时产生的,但是解释器破坏已经到了甚至sys模块不再包含任何可用内容的地步。线程实现在sys.stderr内部保留了一个引用,这样它就可以告诉你一些事情(特别是你看到的确切消息),但是太多的解释器已经被破坏,无法告诉你关于发生了什么问题的任何其他信息。
So find a way to shut down your threads cleanly instead (and remove .daemon = True). Don't know enough about your problem to suggest a specific way, but you'll think of something ;-)
因此,找到一种方法来干净地关闭您的线程(并删除.daemon = True)。对您的问题了解得不够多,无法提出具体的建议,但您会想到一些事情 ;-)
BTW, I'd suggest removing the maxsize=0arguments on your Queue()constructors. The default is "unbounded", and "everyone knows that", while few people know that maxsize=0also means "unbounded". That's gotten worse as other datatypes have taken maxsize=0to mean "maximum size really is 0" (the best example of that is collections.deque); but "no argument means unbounded" is still universally true.
顺便说一句,我建议删除构造maxsize=0函数上的参数Queue()。默认是“无界”,“每个人都知道”,而很少有人知道这maxsize=0也意味着“无界”。情况变得更糟,因为其他数据类型maxsize=0表示“最大大小确实是 0”(最好的例子是collections.deque);但“没有论证就意味着无界”仍然普遍适用。

