【问题标题】:Prevent a second process from listening to the same pipe in Python防止第二个进程在 Python 中监听同一个管道
【发布时间】:2014-03-11 03:03:34
【问题描述】:

我有一个进程使用 Python 2.7 的 multiprocessing.Listener() 连接到管道,并等待带有 recv() 的消息。我在 Windows 7 和 Ubuntu 11 上运行它。

在 Windows 上,管道称为 \\.\pipe\some_unique_id。在 Ubuntu 上,管道称为 /temp/some_unique_id。除此之外,代码是一样的。

一切正常,直到在一个不相关的错误中,monit 启动了同一程序的第二个副本。它会尝试监听完全相同的管道。

我天真地*预计第二次连接尝试会失败,而第一次连接不会受到影响。

相反,我发现行为是officially undefined

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

在 Ubuntu 上,较早的副本似乎被忽略,并且没有任何消息,而最新版本胜出。

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

有没有办法独占打开管道,所以第二个进程无法打开管道,而第一个进程没有关闭或退出?

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

我查看的其他 SO 问题:

【问题讨论】:

    标签: python sockets pipe


    【解决方案1】:

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

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

    如果脚本的两个实例具有相同的 UID 和 GID,您可以尝试在托管于 github 的 Skip Montanaro 的 FileLock 中实现文件锁定。 YMMV。

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

    您也可以尝试使用 Python System V semaphore 来防止同步访问。

    【讨论】:

    • 谢谢,乔纳森。 /var/lock、UIDs/GIDs 和 System V 信号量都排除了 Windows,这是目标之一。 FileLock 看起来很有趣(尽管在 Alpha 版中)。 /var/lock 是使用 pid 文件的类似方法,我一直在考虑尝试。
    猜你喜欢
    • 1970-01-01
    • 2013-06-17
    • 2021-10-28
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2015-03-12
    • 1970-01-01
    相关资源
    最近更新 更多