TL;DR:当stdin/stdout不可用时,我如何生成不同的python解释器(从python中(并在父级和子级之间创建通信通道?
我希望我的python脚本执行修改的python解释器,并通过某种IPC(如multiprocessing.Pipe
(与解释器运行的脚本通信。
假设我有类似于以下的东西:
subprocess.Popen(args=["/my_modified_python_interpreter.exe",
"--my_additional_flag",
"my_python_script.py"])
它运行良好,执行我的python脚本等等。
我现在想用那个修改过的python解释器建立某种进程间通信。
理想情况下,我想共享类似于multiprocessing.Pipe()
返回值之一的东西,但我需要与修改后的python进程共享该对象(我怀疑即使我这样做,multiprocessing.Pipe
也不会很好地处理(。
虽然发送文本和二进制文件就足够了(我不需要共享python对象或任何东西(,但我确实需要在所有主要的操作系统(windows、Linux、Mac(上都能正常工作。
更多的用例/业务解释
更具体地说,修改后的解释器是IDA附带的IDAPython解释器,它允许在IDA工具中编写脚本。
不幸的是,由于stdio已经大量用于现有的用户界面功能(由IDA提供(,我无法使用stdin/stdout
进行通信。
我正在寻找比我想象的更好的可能性:
- 使用两个(rx和tx通道(硬盘文件并将路径传递给这两个文件作为参数
- 使用本地套接字并将路径作为参数传递
- 在windows上使用内存映射文件和
tagname
,在其他操作系统上使用其他同步方法
在对multiprocessing.Pipe
函数及其返回的multiprocesing.Connection
对象进行了一些修改之后,我意识到Connection
对象的序列化比我最初认为的要简单得多。
Connection
对象有三个描述属性:
fileno
-一个句柄。Unix上的任意文件描述符和windows上的套接字readable
-一个布尔值,用于控制是否可以读取Connection对象writable
-一个布尔值,用于控制是否可以写入Connection对象
这三个属性都可以作为对象属性访问,并且可以通过Connection
类构造函数进行控制。
似乎如果:
- 调用
Pipe
的进程生成一个子进程并共享connection.fileno()
号 - 子进程使用该文件描述符作为句柄创建一个
Connection
对象 - 两个解释器实现的
Connection
对象大致相同(我想这是有风险的部分(
在这两个进程之间Connection.send
和Connection.recv
是可能的,尽管它们不共享相同的解释器构建,并且多处理模块实际上没有用于实例化子进程。
编辑:
请注意,Connection
类在python3中可用作multiprocessing.connection.Connection
,在python2中可用作_multiprocessing.Connection
(可能表明不鼓励使用。YMMV(
采用我的另一个答案是错误的。由于句柄是如何在Windows上的python2中继承的,我无法在Windows机器上获得相同的解决方案。我最终使用了在多处理模块中也能找到的非常优越的Listener
和Client
接口。
我的这个问题讨论了那个错误。