如何正确确保终止使用共享锁的线程?
How to properly ensure termination of a thread that is using a shared Lock?
在__main__
中,我创建了一个新的守护线程来实现对受threading.Lock()
保护的共享状态的非阻塞处理。虽然当程序是 运行 时从外观上看一切正常,但我在退出程序时偶尔会遇到异常,即当守护线程应该终止时:
'NoneType' object has no attribute 'acquire'
代码大致如下:
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()
我对 Python 不太熟悉,因此我可能没有按照预期的方式进行操作,但我的猜测是在 [=13] 之后发生了线程的上下文切换=] 不再可用。这个假设是真的吗?
处理此问题的最佳方法是什么?
我认为最简单的方法是添加一个标志变量:
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.
在__main__
中,我创建了一个新的守护线程来实现对受threading.Lock()
保护的共享状态的非阻塞处理。虽然当程序是 运行 时从外观上看一切正常,但我在退出程序时偶尔会遇到异常,即当守护线程应该终止时:
'NoneType' object has no attribute 'acquire'
代码大致如下:
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()
我对 Python 不太熟悉,因此我可能没有按照预期的方式进行操作,但我的猜测是在 [=13] 之后发生了线程的上下文切换=] 不再可用。这个假设是真的吗?
处理此问题的最佳方法是什么?
我认为最简单的方法是添加一个标志变量:
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.