线程和条件:调试获取

时间:2015-07-15 13:16:04

标签: python multithreading

我的一个程序中有一个奇怪的问题,一个线程获取一个条件,另一个线程告诉我没有获取条件。

我做了一些调试信息,以便知道线程是否已经获得了条件,看起来是的,他做到了。但另一个线程告诉我,条件没有获得。

以下是关于我是如何做到这一点的总结(并不是很简短,很抱歉),以及我的输出:

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,即使我已经获得了这个条件?

1 个答案:

答案 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 !