在多个进程上实现tornado.locks.Lock

时间:2016-10-17 22:02:19

标签: python tornado

我一直在思考如何在多个进程上实现龙卷风锁定。

我有多个具有相同协同例程的进程。我不希望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()类为每个进程创建一个单独的实例...如何在多个进程上共享同一个对象?

2 个答案:

答案 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)

如果其中一个流程失败并且需要处理此案例,我理解您的观点。这似乎有用,或者您是否看到这种方法与异步和我正在做的事情有其他问题?

感谢