python-3.x - 在 python 中与子进程交互的最佳实践是什么

标签 python-3.x subprocess

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

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

  • 它在子进程中使用批量作业启动脚本

     process = subprocess.Popen(['python', job_script, src_path], stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE, shell=True)
    
  • 它使用winevt.EventLog模块监听系统事件

     EventLog.Subscribe('System', 'Event/System[Level<=2]', handle_event)
    
  • 如果发生错误,它会关闭所有内容并重新启动脚本。

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

Within the subprocess there's an object controlling everything and continuously collecting generated data. In order to not having to start the whole job from the beginnig, after re-starting the script, this object has to be dumped using pickle (which isn't the problem here!)

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

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

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

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

兄弟, 麦克风

最佳答案

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

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

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

编辑以添加示例脚本:

main.py

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()

Doc2.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')

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

关于python-3.x - 在 python 中与子进程交互的最佳实践是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67164085/

相关文章:

python - 如何使用异步 for 循环遍历列表?

python-3.x - Python asyncio 模块中的 create_connection() 方法

python-3.x - 在三列 Pandas 上应用 RMS 公式

python - 哪些 python neo4j 驱动程序稳定/生产就绪?

Python subprocess.check_call( ["wine"]..) 存在同步问题

python - 子进程似乎无法在pyinstaller exe文件中工作

python - Python3中的打印功能

python - 使用Python C API时如何中断Windows上的Python子进程?

python - 在 Python 中为调用的 shell 脚本提供输入

python - 通过将 git 命令传递给 python 中的子进程来获取最后一次 git 提交日期