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. 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.
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:
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:
Exception in thread Thread-3 (most likely raised during interpreter shutdown)
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. 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.