首页 > 解决方案 > 与python中的子进程交互的最佳实践是什么

问题描述

我正在构建一个应用程序,旨在在另一个软件中进行批量处理数据。为了自动控制其他软件,我正在使用pyautoit,除了不时发生的外部软件引起的应用程序错误外,一切正常。

为了处理这些情况,我建立了一个看门狗:

好的,如果发生系统错误事件,则应该以某种方式处理此事件,即通知 supprocess。然后,此通知应导致子流程中的以下操作:

在子流程中,有一个对象控制一切并不断收集生成的数据。为了不必从头开始整个工作,在重新启动脚本后,必须使用 pickle 转储该对象(这不是问题!)

从子进程内部监听系统事件不起作用。当调用 subprocess.Popen() 时,它会导致一个连续的循环。

所以,我的问题是如何从子进程内部订阅系统事件,或者在父进程和子进程之间进行通信 - 意味着发送一条消息,如“嘿,发生错误”,在子进程中侦听然后创建转储?

我真的很抱歉在这种情况下不允许发布任何代码。但我希望(并且实际上认为)我的描述应该是可以理解的。我的问题是关于使用哪个模块以最好的方式完成此任务?

如果有人能指出我正确的方向,我会很高兴......

溴,麦克风

标签: python-3.xsubprocess

解决方案


我相信最好的答案可能在这里:https ://docs.python.org/3/library/subprocess.html#subprocess.Popen.stdin

这些属性应该允许不同进程之间的适当通信相当容易,并且没有任何其他依赖关系。

请注意,如果其他进程可能导致问题,则 Popen.communicate() 可能更适合。

编辑以添加示例脚本:

主文件

from subprocess import *
import sys

def check_output(p):
    out = p.stdout.readline()
    return out

def send_data(p, data):
    p.stdin.write(bytes(f'{data}\r\n', 'utf8'))  # auto newline
    p.stdin.flush()

def initiate(p):
    #p.stdin.write(bytes('init\r\n', 'utf8'))  # function to send first communication
    #p.stdin.flush()
    send_data(p, 'init')
    return check_output(p)

def test(p, data):
    send_data(p, data)
    return check_output(p)

def main()
    exe_name = 'Doc2.py'
    p = Popen([sys.executable, exe_name], stdout=PIPE, stderr=STDOUT, stdin=PIPE)
    
    print(initiate(p))
    print(test(p, 'test'))
    print(test(p, 'test2'))  # testing responses
    print(test(p, 'test3'))

if __name__ == '__main__':
    main()

文档2.py

import sys, time, random

def recv_data():
    return sys.stdin.readline()

def send_data(data):
    print(data)

while 1:
    d = recv_data()
    #print(f'd: {d}')
    if d.strip() == 'test':
        send_data('return')
    elif d.strip() == 'init':
        send_data('Acknowledge')
    else:
        send_data('Failed')

这是我能想到的跨进程通信的最佳方法。还要确保所有请求和响应不包含换行符,否则代码将中断。


推荐阅读