I'm trying to make threaded flight software for a project in Python 3.4, in which I need threads to restart themselves in case an I/O error occurs during a sensor read or another fluke crash like that. Therefore I am working on making a watchdog to check if threads have died and restarting them.
At first I attempted to just check if the thread was no longer alive and restart it, which did this:
>>> if not a_thread.isAlive():
... a_thread.start()
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "c:Python34libhreading.py", line 847, in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
This behaviour makes sense from the standpoint of threading
and Python itself, but makes my job harder. So I implemented a solution using a dictionary to store the initial thread and copy it to a new object and start it when necessary. Unfortunately this doesn't work either.
Here's a basic example:
import threading
import logging
import queue
import time
from copy import copy, deepcopy
def a():
print("I'm thread a")
def b():
print("I'm thread b")
# Create thread objects
thread_dict = {
'a': threading.Thread(target=a, name='a'),
'b': threading.Thread(target=b, name='b')
}
threads = [copy(t) for t in thread_dict.values()]
for t in threads:
t.start()
for i in range(len(threads)):
if not threads[i].isAlive():
temp = thread_dict[threads[i].name]
threads[i] = deepcopy(temp)
threads[i].start()
thread(i).join(5)
which returns:
I'm thread a
I'm thread b
Traceback (most recent call last):
File "main_test.py", line 25, in <module>
threads[i] = deepcopy(temp)
File "c:Python34libcopy.py", line 182, in deepcopy
y = _reconstruct(x, rv, 1, memo)
... (there's about 20 lines of traceback within copy)
File "c:Python34libcopyreg.py", line 88, in __newobj__
return cls.__new__(cls, *args)
TypeError: object.__new__(_thread.lock) is not safe, use _thread.lock.__new__()
So apparently threading
objects are not safe to copy... Is there anyway to restart threads short of recreating the entire object?