我的一个程序中有一个奇怪的问题,一个线程获取一个条件,另一个线程告诉我没有获取条件。
我做了一些调试信息,以便知道线程是否已经获得了条件,看起来是的,他做到了。但另一个线程告诉我,条件没有获得。
以下是关于我是如何做到这一点的总结(并不是很简短,很抱歉),以及我的输出:
import logging
import time
from threading import Condition, Lock, Thread
logging.basicConfig(level=logging.DEBUG)
class MyClass:
def __init__(self):
self._is_alive = False
self._thread_update = None
self._conditioned_thread = None
self._thread_condition = Condition(Lock()) # Or RLock() or nothing, same issue
def start(self):
self._is_alive = True
self._thread_update = Thread(target=self._loop_update, name="Updater")
self._conditioned_thread = Thread(target=self._loop_conditioned, name="Conditioned")
self._thread_update.start()
self._conditioned_thread.start()
def _loop_conditioned(self):
logging.debug("Starting conditioned thread")
with self._thread_condition:
while self._is_alive:
logging.debug("Awaiting... Is acquired ? %s", self._thread_condition._is_owned())
self._thread_condition.wait()
logging.debug("Success !")
def _loop_update(self):
time.sleep(1)
logging.debug("Notifying ! Is acquired ? %s", self._thread_condition._is_owned())
self._thread_condition.notify(1)
# Do some stuff
def stop(self):
self._is_alive = False
self._thread_condition.notify()
self._thread_update.join()
self._thread_condition.join()
if __name__ == "__main__":
c = MyClass()
c.start()
time.sleep(4)
c.stop()
这是输出:
DEBUG:root:Starting conditioned thread
DEBUG:root:Awaiting... Is acquired ? True
DEBUG:root:Notifying ! Is acquired ? False
Exception in thread Updater:
Traceback (most recent call last):
File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File ".../test.py", line 39, in _loop_update
self._thread_condition.notify(1)
File "/usr/lib64/python2.6/threading.py", line 274, in notify
raise RuntimeError("cannot notify on un-acquired lock")
RuntimeError: cannot notify on un-acquired lock
Traceback (most recent call last):
File ".../test.py", line 53, in <module>
c.stop()
File ".../test.py", line 45, in stop
self._thread_condition.notify()
File "/usr/lib64/python2.6/threading.py", line 274, in notify
raise RuntimeError("cannot notify on un-acquired lock")
RuntimeError: cannot notify on un-acquired lock
问题是为什么我有RuntimeError,即使我已经获得了这个条件?
答案 0 :(得分:1)
答案后的正确代码:
import logging
import time
from threading import Condition, Lock, Thread
logging.basicConfig(level=logging.DEBUG)
class MyClass:
def __init__(self):
self._is_alive = False
self._thread_update = None
self._conditioned_thread = None
self._thread_condition = Condition()
def start(self):
self._is_alive = True
self._thread_update = Thread(target=self._loop_update, name="Updater")
self._conditioned_thread = Thread(target=self._loop_conditioned, name="Conditioned")
self._thread_update.start()
self._conditioned_thread.start()
def _loop_conditioned(self):
logging.debug("Starting conditioned thread")
with self._thread_condition:
while self._is_alive:
logging.debug("Awaiting... Is acquired ? %s", self._thread_condition._is_owned())
self._thread_condition.wait()
logging.debug("Success !")
def _loop_update(self):
time.sleep(1)
self._thread_condition.acquire()
logging.debug("Notifying ! Is acquired ? %s", self._thread_condition._is_owned())
self._thread_condition.notify()
self._thread_condition.release()
# Do some stuff
def stop(self):
self._is_alive = False
with self._thread_condition:
self._thread_condition.notify()
self._thread_update.join()
self._conditioned_thread.join()
if __name__ == "__main__":
c = MyClass()
c.start()
time.sleep(4)
c.stop()
输出:
DEBUG:root:Starting conditioned thread
DEBUG:root:Awaiting... Is acquired ? True
DEBUG:root:Notifying ! Is acquired ? True
DEBUG:root:Success !
DEBUG:root:Awaiting... Is acquired ? True
DEBUG:root:Success !