我一直在思考如何在多个进程上实现龙卷风锁定。
我有多个具有相同协同例程的进程。我不希望C2在C1运行时运行,反之亦然(即使是跨进程)
有没有人对如何使用tornado.locks.Lock实现这一点有任何想法?
p1 p2 p3
C1 C1 C1
C2 C2 C2
我一直在阅读有关multiprocessing.managers.SyncManager我启动了一个服务器,然后在龙卷风中 init 我尝试连接到它:
m = SyncManager(address=("", 50000), authkey=b'abc')
m.connect()
然后我获得了锁定:
check=lock.acquire(blocking=False)
我开始了另一个龙卷风过程并做了同样的事情。但是Lock()类为每个进程创建一个单独的实例...如何在多个进程上共享同一个对象?
答案 0 :(得分:2)
您无法使用tornado.lock.Lock
执行此操作;这是一个单进程同步原语(并且它对multiprocessing
SyncManager
一无所知。您可以使用SyncManager.Lock
来获取多进程锁,但它是同步的,所以你不能从异步龙卷风应用程序中轻松使用它。
您需要与一些外部协调流程进行对话以处理跨多个流程的锁定,即使这样,您也必须处理流程在保持锁定时死亡的可能性(因此您需要允许锁定到期不知何故,并处理锁定到期的情况,而持有它的进程实际上并没有死...)。我建议使用etcd
或ZooKeeper之类的东西作为锁定服务。
答案 1 :(得分:0)
嗨Ben感谢您的上述回复。我最终使用了Lock:
from multiprocessing import Process, Lock
在我的main()
中,我实例化Lock()
并生成一个启动龙卷风服务器的新进程。我通过锁(l)然后将其存储在龙卷风应用程序中:
if __name__ =='__main__':
l=Lock()
Process(target=runServer,args=(l,8000)).start()
Process(target=runServer,args=(l,8001)).start()
def runServer(lock,port):
app=Application(lock,port)
# start tornado server here
class Application(tornado.web.Application):
def __init__(self,lock,port):
# Store the lock
self.lock=lock
我有一些依赖于等待此锁定成为免费的协同例程。在合作例程中,我有以下内容:
while (not self.lock.acquire(block=False)):
yield tornado.gen.sleep(.01)
如果其中一个流程失败并且需要处理此案例,我理解您的观点。这似乎有用,或者您是否看到这种方法与异步和我正在做的事情有其他问题?
感谢