代码之家  ›  专栏  ›  技术社区  ›  tipu

将线程置于休眠状态,直到事件x发生为止

  •  6
  • tipu  · 技术社区  · 15 年前

    我正在一个线程应用程序中写入许多文件,并为每个文件创建一个处理程序。我有handlerFactory类来管理这些处理程序的分发。我想做的是

    线程A请求并从handlerFactory类获取foo.txt的文件句柄

    线程B请求foo.txt的文件处理程序

    处理程序类识别此文件句柄已签出

    处理程序类使线程A进入睡眠状态

    线程B使用handlerFactory中的包装方法关闭文件句柄

    handlerFactory通知休眠线程

    线程B唤醒并成功获取foo.txt的文件句柄

    这就是我迄今为止所拥有的,

    def get_handler(self, file_path, type):
        self.lock.acquire()
        if file_path not in self.handlers:
            self.handlers[file_path] = open(file_path, type)
        elif not self.handlers[file_path].closed:
            time.sleep(1)
        self.lock.release()
        return self.handlers[file_path][type]
    

    我相信这涵盖了睡眠和处理程序检索的成功,但我不确定如何唤醒所有线程,或者更好地唤醒特定线程。

    3 回复  |  直到 15 年前
        1
  •  6
  •   Dawnkeeper    8 年前

    您要查找的是一个条件变量。

    Condition Variables

    Here 是python 2库引用。
    对于python 3,可以找到 here

        2
  •  2
  •   Alex Martelli    15 年前

    看起来你想要一个 threading.Semaphore 与每个处理程序关联(其他同步对象,如事件和条件也是可能的,但信号量似乎最简单,以满足您的需要)。(具体来说,使用 BoundedSemaphore :对于您的用例,这将立即引发一个异常,因为编程错误错误错误地释放信号电话的次数超过了它们获取的次数——这正是 有界的 Semanphone的版本;-)。

    将每个信号量初始化为值 1 当您构建它时(这意味着处理程序是可用的)。每次使用线程调用 acquire 在信号量上获取处理程序(可能会阻塞它),以及 release 当处理程序完成时(这将恰好取消阻塞一个等待的线程)。这比条件的获取/等待/通知/发布生命周期要简单,而且也有更多的未来证据,因为正如条件文档所说:

    当前的实现被唤醒 只有一根线,如果有的话 等待。然而,不安全的是 依靠这种行为。未来, 优化实施可能 偶尔醒来不止一个 线程。

    当你使用信号灯时,你是安全的(语义 安全可靠:如果信号量初始化为n,则始终有0到n-1[[包含]]个线程成功获取信号量,但尚未释放它)。

        3
  •  0
  •   vy32    15 年前

    您确实意识到Python有一个巨大的锁,所以您无法获得多线程的大部分好处,对吧?

    除非主线程对每个工作线程的结果做了一些处理,否则您可能希望考虑为每个请求分叉另一个进程。那么您就不必处理锁定问题了。让孩子们做他们需要做的,然后死去。如果它们确实需要进行通信,那么可以通过管道、xmlrpc或通过sqlite数据库(即threadsafe)进行通信。