Python 如何在不泄漏手柄的情况下进行本地IPC(跨平台)?

Python 如何在不泄漏手柄的情况下进行本地IPC(跨平台)?,python,cross-platform,ipc,resource-leak,Python,Cross Platform,Ipc,Resource Leak,如何使用子进程启动IPC,而不让它继承所有句柄?为了让它更有趣,这应该在windows和unix上都适用 背景:我正在编写一个库,它与3rparty共享库(我们称之为3rparty共享库)接口,而3rparty共享库又包含全局数据(实际上应该是对象!)。我想拥有此全局数据的多个实例。据我所知,我有两个选择来解决这个问题: 创建一个cython模块,该模块链接到它的静态变体,然后在需要新实例时复制并导入该模块。类似地,我可以复制它,但创建ctypes接口需要更多的工作 生成加载它的子进程,并与之建

如何使用子进程启动IPC,而不让它继承所有句柄?为了让它更有趣,这应该在windows和unix上都适用

背景:我正在编写一个库,它与3rparty共享库(我们称之为3rparty共享库)接口,而3rparty共享库又包含全局数据(实际上应该是对象!)。我想拥有此全局数据的多个实例。据我所知,我有两个选择来解决这个问题:

  • 创建一个cython模块,该模块链接到它的静态变体,然后在需要新实例时复制并导入该模块。类似地,我可以复制它,但创建ctypes接口需要更多的工作

  • 生成加载它的子进程,并与之建立IPC连接

  • 使用(2)有几个原因:

    • 我不确定(1)是否在任何方面都是可靠的,这感觉是个坏主意(当应用程序以不受控制的方式退出时,所有额外的模块会发生什么情况?)

    • 出于安全考虑,将其装箱到单独的流程中实际上可能是一个好主意:它处理潜在的不安全输入,并且其代码质量不太好。因此,我不希望在运行它时打开任何安全资源

    • 在未来的应用中,这种IPC可能有很多需求

    那么我有什么选择呢?我已经研究过:

    • multiprocessing.Process
      一开始看起来不错,直到我意识到新进程得到了我所有句柄的副本。不用说,这是一个相当大的问题,因为现在不能通过在父进程中关闭资源来可靠地释放资源+前面提到的安全问题

    • multiprocessing.Process
      中使用
      os.closerange
      手动关闭所有句柄-我感兴趣的管道除外。
      os.closerange
      是只关闭文件还是同时处理其他类型的资源?如果是:给定
      管道
      对象,如何确定范围

    • subprocess.Popen(..,close_fds=True,stdin=PIPE,stdout=PIPE)
      在unix上运行良好,但在win32上不可能

    • win32和unix上的命名管道非常不同。他们有没有任何图书馆可以帮助他们使用

    • 插座。很有希望,特别是因为它们是方便的RPC库,可以使用套接字。另一方面,我担心这可能会导致一系列安全问题。我确定为本地来源的套接字(
      sock.getpeername()[0]==“127.0.0.1”
      )是否可以防止回火

    有没有我忽略的可能性

    总结:主要的问题是如何在windows+unix上建立一个安全的IPC和一个子进程?但如果你只知道部分问题的答案,请不要犹豫回答


    感谢您抽出时间阅读

    在python上似乎>=3.4
    子流程。Popen(…,stdin=PIPE,stdout=PIPE,close_fds=False)
    是一个可能的选项。这是由于一个补丁使得默认情况下所有打开的文件描述符都不可继承。更准确地说,它们将在
    execv
    上自动关闭(因此仍然无法使用
    多处理.Process
    ),请参阅

    这也是其他python版本的有效选项:

    • 在windows上,默认情况下创建的句柄不可继承,因此您将只泄漏显式可继承的句柄
    • 关于POSIX/python