[英]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.