我和我的朋友一直在从事一个大型项目,以在python和PyGame中学习和娱乐。基本上,这是一个小村庄的AI模拟。我们想要一个昼夜循环,所以我找到了一种使用numpy改变整个表面颜色的巧妙方法(特别是交叉淡入淡出的教程)-http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro 。 html
我将其实现到代码中,并且可以正常工作,但是速度非常慢,例如<1 fps慢。所以我研究了线程(因为我想最终添加它),并在Queues上找到了此页-了解python中的Queue模块(如何运行)
我花了大约15分钟来制作一个基本系统,但是一旦我运行它,窗口就会关闭并且它说
Exception in thread Thread-1 (most likely raised during interpreter shutdown):
编辑:这就是它所说的一切,没有回溯错误
我不知道自己在做什么错,但是我想我缺少一些简单的东西。我在下面的代码中添加了必要的部分。
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()
如果有人可以帮助,将不胜感激。谢谢。
使用守护程序线程时,这很常见。为什么要.daemon = True在线程上设置?想一想。尽管守护程序线程有合法用途,但 大多数情况下 程序员会这样做,因为它们很困惑,例如“我不知道如何彻底关闭线程,否则,程序将在退出时冻结,所以我知道!我将说它们是守护程序线程。然后,解释器将不等待它们退出时终止。问题已解决。”
.daemon = True
但这并没有解决- 通常只会带来其他问题。特别是,守护程序线程将继续运行,而解释器将在退出时自行销毁。模块被销毁,stdin和stdout和stderr被销毁,等等,等等。然后,由于它们试图访问的东西被歼灭,各种事情都可能在守护程序线程中出错。
您看到的特定消息是在某个线程中引发异常时产生的,但是到目前为止,解释器的销毁甚至使该sys模块不再包含任何可用的东西。该线程执行保留的引用sys.stderr内部,以便它可以告诉你 的东西 ,然后(具体而言,您所看到的确切消息),但过多的解释器已被摧毁告诉你别的什么地方出了错。
sys
sys.stderr
因此,找到一种方法来彻底关闭线程(并删除.daemon = True)。对您的问题了解不足,无法提出具体的方法,但是您会想到的;-)
顺便说一句,我建议删除构造maxsize=0函数上的参数Queue()。默认值为“无界”和“每个人都知道”,而很少有人知道这maxsize=0也意味着“无界”。随着其他数据类型已经maxsize=0表示“最大大小确实为0”(最好的例子是collections.deque),情况变得更糟。但是“没有论据意味着无限”仍然普遍存在。
maxsize=0
Queue()
collections.deque