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