如何在不让其继承所有句柄的情况下使用子进程启动IPC?为了使它更有趣,此功能应在Windows以及UNIX上均有效。
背景:我正在编写一个与3rparty共享库(简称IT)接口的库,该库又包含全局数据(实际上应该是对象!)。我想拥有此全局数据的多个实例。据我了解,我有两个解决方案:
创建一个与IT的静态变型链接的cython模块,然后在需要新实例时复制并导入该模块。类似地,我可以复制IT,但是创建ctypes接口的工作量更大。
产生一个加载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版本也是有效的选项:
有关相应的示例,请参见:
https://github.com/coldfix/python-ipc-test
最有用的组合是:
stdio:腌
Inherit_unidir:挑剔
插座:袜子
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句