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

修补程序

如何在不让其继承所有句柄的情况下使用子进程启动IPC?为了使它更有趣,此功能应在Windows以及UNIX上均有效。

背景:我正在编写一个与3rparty共享库(简称IT)接口的库,该库又包含全局数据(实际上应该是对象!)。我想拥有此全局数据的多个实例。据我了解,我有两个解决方案:

  1. 创建一个与IT的静态变型链接的cython模块,然后在需要新实例时复制并导入该模块。类似地,我可以复制IT,但是创建ctypes接口的工作量更大。

  2. 产生一个加载IT的子流程,并建立一个IPC连接。

有几个原因可以使用(2):

  • 我不确定(1)是否以任何方式可靠,并且感觉像是一个坏主意(当应用程序以不受控制的方式退出时,所有其他模块会发生什么情况?)。

  • 出于安全考虑,将IT分为单独的流程实际上可能是一个好主意:IT处理潜在的不安全输入,并且IT的代码质量并不是很好。因此,我宁愿在运行它时也不要打开任何安全资源。

  • 在未来的应用中可能需要大量此类IPC

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

  • multiprocessing.Process起初看起来不错,直到我意识到新过程会得到我所有手柄的副本。不用说,这是很成问题的,因为现在无法通过在父进程中关闭资源以及前面提到的安全问题来可靠地释放资源。

  • os.closerange在a中使用可以multiprocessing.Process手动关闭所有句柄-我感兴趣的Pipe除外。os.closerange仅关闭文件还是可以处理其他类型的资源?如果是这样:给定Pipe对象,如何确定范围

  • 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上似乎subprocess.Popen(..., stdin=PIPE, stdout=PIPE, close_fds=False)是一个可能的选项。这是由于存在一个修补程序,该修补程序默认情况下使所有打开的文件描述符都不可继承。更精确地说,它们将自动关闭execv(因此仍然无法使用multiprocessing.Process),请参阅PEP 446

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

  • 在Windows上,默认情况下创建的HANDLEs是不可继承的,因此您将只泄漏显式可继承的句柄
  • 在POSIX / python <= 3.3上,生成子进程后,仍然可以使用os.closerange关闭打开的文件描述符

有关相应的示例,请参见:

https://github.com/coldfix/python-ipc-test

最有用的组合是:

  1. stdio:腌

    • 专家:我的测试中完全跨平台
    • 专业版:最快的选择(2个)
    • 缺点: stdin / stdout不能独立重定向
  2. Inherit_unidir:挑剔

    • 优点:您可以独立重定向STDIO流
    • 专业人士:与stdio:pickle一起最快的选择
    • 缺点:平台级别很低的特定代码
  3. 插座:袜子

    • 优点:毫不费力地跨平台
    • 缺点 “攻击者”可能会在短时间内连接到端口,您可能需要输入密码或其他密码来防止这种情况的发生
    • 缺点:比Windows上的替代品稍慢(在我的测量中系数为1.6)
    • 不使用AF_UNIX时,在Linux上会有无法预测的性能影响

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在不锁定的情况下对具有关联ID的单身人士进行“跨层”多线程处理?

如何在没有qmlscene的情况下创建跨平台的Ubuntu Touch应用程序?

如何在不递归的情况下进行ls

如何在不写select的情况下进行分组

使用存储库模式,如何在不创建泄漏抽象的情况下引用域模型?

如何在不泄漏任何安全信息或堆栈跟踪的情况下记录错误?

如何在不泄漏内存的情况下从C实现Vec的Rust结构和方法?

如何在不内存泄漏的情况下删除C中的前导/后缀空格

如何在不破坏功能的情况下隐藏跨浏览器的滚动条

如何在不进行繁琐的转换的情况下跨这些列应用函数?

如何在不轮询的情况下使本地git镜像保持最新?

如何在不创建本地文件的情况下使用OpenXML创建Excel文件?

如何在不更改主分支的情况下更改本地 git 存储库的功能分支?

如何在不更改本地代码的情况下撤消git push?

如何在不键入.local的情况下解析“链接本地”主机

我如何在不传递句柄参数的情况下使用Delphi在dll项目中获取主机应用程序句柄

如何在没有Internet连接的情况下通过本地网络进行WebRTC?

如何在没有随机的情况下对结构进行本地哈希处理?

如何在不更改Google Apps脚本的情况下进行Json解析

如何在不执行几个连续查询的情况下对其进行解释?

如何在不获取整个表格的情况下进行分页?

Angular 如何在不更改 URL 的情况下使用参数进行路由

如何在不评估数学表达式的情况下进行分配

Prismic-如何在不暴露访问令牌的情况下进行API调用

R:如何在不声明的情况下通过数组符号对列表进行子集化?

如何在不扩展轴范围的情况下进行绘图?

如何在不创建sed中间文件的情况下进行替换?

如何在不选择计数器的情况下进行计数?

如何在不破坏角度模型的情况下对其进行过滤