简体   繁体   English

Python线程:解释器关闭异常

[英]Python threading: interpreter shutdown exception

I'm writing an emulator for a vintage computer system in Python, and I'm having some trouble with an exception thrown when trying to "restart" the emulator core thread after coming out of a halt condition. 我正在用Python为老式计算机系统编写仿真器,并且在退出暂停状态后尝试“重新启动”仿真器核心线程时遇到异常,我遇到了一些麻烦。 The "run processor" method, part of a larger class looks something like this: 作为较大类的一部分的“运行处理器”方法看起来像这样:

def run_processor(self):
    processor = self

    class processor_thread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self.daemon = True

        def run(self):
            while processor.running:
               #main loop for instruction fetch and decode is here   

    self.processor_thread = processor_thread()
    self.running = True   
    self.processor_thread.start()

I have a main function where I load a memory image into the processor, set the program counter, and run a test program on the emulator. 我有一个主要功能,可以将内存映像加载到处理器中,设置程序计数器,并在模拟器上运行测试程序。 This outputs some stuff to the console, and eventually the processor's "HLT" instruction sets "processor.running" to False, terminating processor_thread. 这会将一些内容输出到控制台,最终处理器的“ HLT”指令将“ processor.running”设置为False,从而终止processor_thread。

This works OK, but where I'm running in to trouble is a test of restarting the processor by calling run_processor a second time: 可以,但是我遇到麻烦的地方是通过再次调用run_processor来重新启动处理器的测试:

processor = Processor(memory, scheduler, interrupts, teleprinter)
processor.program_counter = 128
processor.run_processor()
while processor.processor_thread.isAlive():
    pass
processor.program_counter = 128
processor.run_processor()

The first instance runs fine, but when the run_processor method is called a second time I get the following error: 第一个实例运行良好,但是第二次调用run_processor方法时,出现以下错误:

Exception in thread Thread-3 (most likely raised during interpreter shutdown) 线程Thread-3中的异常(很可能在解释器关闭期间引发)

How can I rectify this? 我该如何纠正? Thanks. 谢谢。

EDIT: I broke the code down to its bare essentials and found it actually works OK. 编辑:我将代码分解为基本要点,发现它实际上可以正常运行。 I didn't notice that my HALT method was actually written in such a way that it shut down all the processor peripheral threads, including the thread that runs the teleprinter emulator. 我没有注意到我的HALT方法实际上是这样编写的,即它关闭了所有处理器外围线程, 包括运行电传打印机仿真器的线程。 Without the teleprinter to output to it looks like the emulator core crashed on the second test. 没有电传打字机输出到它,好像模拟器核心在第二次测试中崩溃了。

Here's the test case: 这是测试用例:

import threading
import time

class Processor(object):
    def __init__(self):
        self.running = False

    def halt_processor(self):
        self.running = False

    def run_processor(self):
        processor = self

        class processor_thread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)
                self.daemon = True

            def run(self):
                while processor.running:
                   #main loop for instruction fetch and decode is here   
                   print "Hello, I am the main loop doing my thing 1"
                   time.sleep(1)
                   print "Hello, I am the main loop doing my thing 2"
                   time.sleep(1)
                   print "I will halt now."
                   processor.halt_processor()

        self.processor_thread = processor_thread()
        self.running = True   
        self.processor_thread.start()

def test1():
    processor = Processor()
    processor.run_processor()

def test2():
    processor = Processor()
    processor.run_processor()
    while processor.processor_thread.isAlive():
        pass
    processor.run_processor()

def main():
     test2()

if __name__ == '__main__':
    main()

Works OK. 工作正常。

Firstly, you can ignore this error. 首先,您可以忽略此错误。 If your program works, any errors during shutdown could be ignored. 如果您的程序正常运行,则关闭期间的任何错误都可以忽略。 I'm fully with you that this isn't the way things should be and that a clean solution is called for. 我完全支持您,这不是应该的方式,因此需要一个干净的解决方案。

What I think is missing is the call to thread.join() . 我认为缺少的是对thread.join()的调用。 You are currently busy-waiting for the thread to return false from isAlive() (which should be is_alive() , btw), using join() is cleaner and shorter. 您当前正在忙于等待线程从isAlive()返回false(应该为is_alive() ,btw),使用join() is_alive()

BTW: There is no need to derive from the Thread class, which makes the code a bit shorter. 顺便说一句:不需要从Thread类派生,这会使代码短一些。 I personally find it clearer, too, because the Python object is just a handle to the thread and not the thread itself. 我个人也很清楚,因为Python对象只是线程的句柄,而不是线程本身。

The way I see it, the main thread ends just after starting again the Processor thread. 我的看法是,主线程在再次启动Processor线程后才结束。 Have you tried to put a while after starting it? 启动后是否尝试放置while

PS: Also, some nice working code would make debugging much easier for those that want to help. PS:另外,一些不错的工作代码会使想要帮助的人更容易调试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 线程和解释器关闭 - Threading and interpreter shutdown Python线程和解释器关闭 - 这是可修复的还是问题Python问题#Issue14623 - Python Threading and interpreter shutdown- Is this fixable or issue Python Issue #Issue14623 线程 Thread-1 中的 Python 异常(最有可能在解释器关闭期间引发)? - Python Exception in thread Thread-1 (most likely raised during interpreter shutdown)? Python线程未处理的异常 - Python Threading Unhandled Exception Python APScheduler RuntimeError:解释器关闭后无法安排新的期货 - Python APScheduler RuntimeError: cannot schedule new futures after interpreter shutdown Python线程捕获异常并退出 - Python threading Catch Exception and Exit 使用 GIL 和多线程处理嵌入式 Python 解释器调用 - Handling embedded Python interpreter calls with GIL and multi-threading 得到异常错误“线程Thread-1中的异常(很可能在解释器关闭期间引发)”使用Paramiko - Got Exception Error “Exception in thread Thread-1 (most likely raised during interpreter shutdown)” which using Paramiko 得到异常错误“Thread-13线程中的异常(最有可能在解释器关闭期间引发)” - Got Exception Error “Exception in thread Thread-13 (most likely raised during interpreter shutdown)” 如何在python关闭时调试异常 - How do a debug an exception on python shutdown
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM