Reputation: 4928
In __main__
, I create a new daemon thread to achieve a non-blocking processing on a shared state protected by a threading.Lock()
. While everything works fine from the looks of it when the program is running, I sporadically get an exception when quitting the program, i.e. when the daemon thread is supposed to terminate:
'NoneType' object has no attribute 'acquire'
The code is roughly as follows:
mutex = threading.Lock()
def async_processing(shared):
global mutex
while True:
sleep(1)
mutex.acquire()
try:
shared.modify_state()
finally:
mutex.release()
if __name__ == '__main__':
shared = SomeObject()
thread = threading.Thread(target=async_processing, args=(shared,))
thread.daemon = True
thread.start()
if user_enters_some_command_to_stdin:
mutex.acquire()
try:
shared.modify_state()
finally:
mutex.release()
I'm not really at home with Python and am thus maybe not doing this the way it's supposed to be done, but my guess is that somehow a context switch to the thread happens after mutex
is no longer available. Is this hypothesis true?
What is the best way to handle this?
Upvotes: 1
Views: 88
Reputation: 20224
I think the simplest way is adding a flag variable:
mutex = threading.Lock()
flag = True
def async_processing(shared):
while flag:
sleep(1)
with mutex:
shared.modify_state()
if __name__ == '__main__':
shared = SomeObject()
thread = threading.Thread(target=async_processing, args=(shared,))
thread.start()
if some_user_action:
with mutex:
shared.modify_state()
flag = False
thread.join() # wait for exit.
Upvotes: 1