线程Thread-1中的Python异常(最有可能在解释器关闭期间引发)? [英] Python Exception in thread Thread-1 (most likely raised during interpreter shutdown)?

查看:82
本文介绍了线程Thread-1中的Python异常(最有可能在解释器关闭期间引发)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我和我的朋友一直在从事一个大型项目,以在python和PyGame中学习和娱乐.基本上,这是一个小村庄的AI模拟.我们想要一个昼夜循环,所以我找到了一种使用numpy更改整个表面颜色的巧妙方法(特别是交叉淡入淡出的教程)-

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

我将其实现到代码中并且可以工作,但是非常慢,就像<慢1 fps.所以我研究了线程(因为我想最终添加它),并在Queues上找到了此页面-

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)

我花了大约15分钟来制作一个基本系统,但是一旦我运行它,窗口就会关闭并显示

I spend about 15 minutes making a basic system but as soon as I run it, the window closes and it says

Exception in thread Thread-1 (most likely raised during interpreter shutdown):

这就是它的全部意思,没有回溯错误

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.

推荐答案

在使用守护程序线程时,这很常见.为什么要在线程上设置.daemon = True?想一想.尽管守护程序线程有合法用途,但大多数时候程序员都会这么做,因为它们很困惑,例如我不知道如何干净地关闭线程,程序将冻结".如果我不退出,那么我知道!我将说它们是守护程序线程.然后,解释器将不等待它们退出时终止.已解决问题."

This is pretty common when using daemon threads. Why are you setting .daemon = True on your threads? Think about it. While there are legitimate uses for daemon threads, most times 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."

但是它并没有解决-它通常会带来其他问题.特别是,守护程序线程将继续运行,而解释器将在退出时自行销毁.模块被销毁,stdin和stdout和stderr被销毁,等等,等等.然后,由于它们试图访问的东西被歼灭,各种事情都可能在守护程序线程中出错.

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.

您看到的特定消息是在某个线程中引发异常时产生的,但是到目前为止,解释器的销毁甚至使sys模块不再包含任何可用的东西.线程实现在内部保留了对sys.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 sys module no longer contains anything usable. The threading implementation retains a reference to sys.stderr internally so that it can tell you something then (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.

因此,请寻找一种方法来彻底关闭线程(并删除.daemon = True).对问题的了解不足,无法提出具体的方法,但是您会想到的;-)

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 ;-)

顺便说一句,我建议删除Queue()构造函数上的maxsize=0参数.默认值为无界"和每个人都知道",而很少有人知道maxsize=0也表示无界".随着其他数据类型采用maxsize=0表示最大大小确实为0"(最好的例子是collections.deque),情况变得更糟.但是没有参数就意味着无穷无尽"仍然普遍适用.

BTW, I'd suggest removing the maxsize=0 arguments on your Queue() constructors. The default is "unbounded", and "everyone knows that", while few people know that maxsize=0 also means "unbounded". That's gotten worse as other datatypes have taken maxsize=0 to mean "maximum size really is 0" (the best example of that is collections.deque); but "no argument means unbounded" is still universally true.

这篇关于线程Thread-1中的Python异常(最有可能在解释器关闭期间引发)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆