【发布时间】:2010-11-06 07:17:13
【问题描述】:
我正在使用 Twisted 框架,并且正在异步获取 RPC。我有另一个功能,它每 2 秒执行一次任务,并在其间休眠。这是通过reactor.callInThread 调用的。这些依赖于共享资源,所以我需要一些线程安全的方式来访问它们。如何在扭曲中使用临界区/互斥锁/锁?
【问题讨论】:
标签: python multithreading locking twisted mutex
我正在使用 Twisted 框架,并且正在异步获取 RPC。我有另一个功能,它每 2 秒执行一次任务,并在其间休眠。这是通过reactor.callInThread 调用的。这些依赖于共享资源,所以我需要一些线程安全的方式来访问它们。如何在扭曲中使用临界区/互斥锁/锁?
【问题讨论】:
标签: python multithreading locking twisted mutex
虽然您可以在 twisted 中使用线程,但通常使用 twisted 的习惯用法是使用单个线程异步执行 RPC。这是它的优点之一。当 RPC 结果为您准备好时,twisted 框架将运行反应器并调用您的处理程序事件。然后你的代码运行,当你的处理程序退出时,控制权返回反应堆,它将调用下一个准备好代码的处理程序。因此,即使很多事情都是并行进行的,twisted 可以确保一次只有一个函数在运行,因此您不需要任何互斥,只需维护状态变量,以便您的回调知道它们的当前上下文是什么操作就够了。
如果您明确创建线程并将它们与运行的扭曲框架一起使用,您可能需要Standard Python Mutex 之类的东西,尽管您需要非常小心,不要让您的主 Reactor 回调线程等待互斥体在任何时间长度内,反应器内的回调都不应该阻塞。
【讨论】:
Twisted 让您可以在单个线程中编写事件驱动的代码。多个事件可以安全地写入标准的 Python 非线程安全数据结构,并且非线程安全数据结构可以用作互斥体。如果您确实开始使用线程,那么您必须担心这些事情。但您不必使用它们。
因此,正如评论所言:为您的任务使用 task.LoopingCall 或 reactor.CallLater。永远不要调用 time.sleep(),让反应器在正确的时间调用你的任务(并在其间做其他工作)。及时响应您的 RPC。
不会有两个线程同时运行您的代码。但是,您不知道调用回调的顺序。一旦您将控制权交给 Deferred,在您取回它时,应用程序状态可能已经改变。
【讨论】: