防止第二个进程侦听Python中的同一管道

防止第二个进程侦听Python中的同一管道,python,sockets,pipe,Python,Sockets,Pipe,我有一个进程,它使用Python2.7的multiprocessing.Listener()连接到管道,并使用recv()等待消息。我在Windows7和Ubuntu11上运行它 在Windows上,管道称为\\.\pipe\some\u unique\u id。在Ubuntu上,管道称为/temp/some\u unique\u id。除此之外,代码是相同的 所有这些都可以正常工作,直到在一个不相关的bug中,monit启动了同一程序的第二个副本。它试图听完全相同的管道 我天真地*期望第二次连

我有一个进程,它使用Python2.7的
multiprocessing.Listener()
连接到管道,并使用
recv()
等待消息。我在Windows7和Ubuntu11上运行它

在Windows上,管道称为
\\.\pipe\some\u unique\u id
。在Ubuntu上,管道称为
/temp/some\u unique\u id
。除此之外,代码是相同的

所有这些都可以正常工作,直到在一个不相关的bug中,monit启动了同一程序的第二个副本。它试图听完全相同的管道

我天真地*期望第二次连接尝试会失败,第一次连接不会受到破坏

相反,我发现这种行为是错误的

请注意,如果两个进程(或线程)同时尝试读取或写入管道的同一端,管道中的数据可能会损坏

在Ubuntu上,早期版本似乎被忽略,没有任何消息,而最新版本则获胜

在Windows上,有一些更复杂的行为。有时,原始管道在调用
recv()
时引发EOFError异常。有时,两个侦听器可以共存,并且每条消息可以任意分发

是否有方法以独占方式打开管道,以便在第一个进程未关闭或退出时,第二个进程无法打开管道?

*我可以发誓我手动测试了这个精确的场景,但显然我没有

我还研究了其他一些问题:

  • -我(明知)没有设置
    SO\u REUSEADDR
  • -不涉及分叉

命名管道与常规文件具有相同的访问符号。任何具有读写权限的进程都可以打开管道进行读写

如果您有办法保证Python脚本的两个实例由具有不同UID或GID的进程调用,那么您可以使用文件权限实现唯一的访问控制

如果脚本的两个实例具有相同的UID和GID,则可以尝试在Skip Montanaro的hosted on中实现文件锁定。YMMV

实现这一点的更简单方法可能是在/var/lock中创建一个锁文件,其中包含创建锁文件的进程的PID,然后在打开管道之前检查锁文件是否存在。大多数长时间运行的守护进程都使用此方案,但当创建锁文件的进程在阻止它们删除锁文件的情况下终止时会出现问题


您也可以尝试使用Python来阻止同步访问。

谢谢,Jonathan/var/lock、UIDs/GIDs和systemv信号量都不包括作为目标之一的窗口<代码>文件锁看起来很有趣(尽管是Alpha格式)/var/lock是使用pid文件的类似方法,我一直在考虑尝试。