Python Twisted中的互斥锁
我正在使用Twisted框架,并且正在异步接收远程过程调用(RPC)。我还有一个函数每2秒执行一次任务,并在两次执行之间休眠。这是通过reactor.callInThread来调用的。这些任务依赖于共享资源,所以我需要一种线程安全的方法来访问这些资源。在Twisted中,如何使用关键区段、互斥锁或锁呢?
2 个回答
Twisted让你可以在一个线程中编写基于事件的代码。多个事件可以安全地写入标准的Python非线程安全的数据结构,而这些非线程安全的数据结构也可以用作互斥锁。如果你确实开始使用线程,那么你就需要关注这些问题。但其实你并不一定要使用线程。
所以,正如评论中所说的:使用task.LoopingCall或者reactor.CallLater来处理你的任务。千万不要调用time.sleep(),让反应器在合适的时间调用你的任务(并在这期间做其他工作)。及时响应你的RPC请求。
你的代码不会同时有两个线程在运行。不过,你无法预测你的回调函数会按什么顺序被调用。一旦你把控制权交给了Deferred,等你再拿回来时,应用的状态可能已经改变了。
虽然你可以在Twisted中使用线程,但通常的做法是通过单线程异步地进行远程过程调用(RPC)。这就是它的一个优点。Twisted框架会运行一个“反应器”,当RPC的结果准备好时,它会调用你的处理程序。然后你的代码就会执行,当处理程序结束后,控制权会返回给反应器,反应器会调用下一个准备好的处理程序。所以尽管有很多事情在并行进行,Twisted确保一次只有一个函数在运行,因此你不需要使用互斥锁,只需维护状态变量,让你的回调函数知道它们当前的上下文就足够了。
如果你明确地创建线程并在运行的Twisted框架中使用它们,你可能需要像标准Python互斥锁这样的东西。不过你需要非常小心,确保你的主反应器回调线程不会长时间等待互斥锁,因为反应器内部的回调不应该被阻塞。