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

2024-10-06 12:35:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在一个线程应用程序中写入许多文件,并为每个文件创建一个处理程序。我有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]

我相信这将成功地覆盖休眠和处理程序检索,但我不确定如何唤醒所有线程,甚至更好地唤醒特定线程。


Tags: 文件pathselftxtlock应用程序处理程序foo
3条回答

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

在构建每个信号量时,将其初始化为1的值(这意味着处理程序可用)。每一个使用线程调用信号量上的acquire来获取处理程序(可能会阻塞它),并在处理完处理程序后对其进行release(这将恰好取消阻塞一个等待的线程)。这比条件的获取/等待/通知/发布生命周期更简单,也更能证明未来,因为正如条件文档所说:

The current implementation wakes up exactly one thread, if any are waiting. However, it’s not safe to rely on this behavior. A future, optimized implementation may occasionally wake up more than one thread.

当使用一个信号量时,您可以安全地使用它(其中的语义是可以安全依赖的:如果一个信号量被初始化为N,则始终有0到N-1[[included]]个线程成功地获取了该信号量,但尚未释放它)。

你确实意识到Python有一个巨大的锁,所以多线程的大部分好处你都得不到,对吧?

除非主线程有理由对每个工作线程的结果执行某些操作,否则您可能希望考虑为每个请求派生另一个进程。那么你就不必处理锁定问题了。让孩子们做他们需要做的事,然后死去。如果他们确实需要通信,可以通过管道、XMLRPC或sqlite数据库(这是线程安全的)进行通信。

你要找的是一个条件变量。

Condition Variables

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

相关问题 更多 >