0%

python进程启动其他进程之后命令行无响应如何解决

Ubuntu之下python使用subprocess启动新的进程之后命令行没有任何反应

  • 启动进程之后,主进程和子进程都在正常运行,但是用户无法通过命令行对其输入任何内容,也无法使用Ctrl+C对其执行任何操作,均表现为无响应
  • 此时可能是因为新任务启动之后,两个进程共用命令行的stdinstdout冲突导致的
  • 两个进程并发的向同一个命令行输出,可能是出现某些问题导致无法输入内容

    解决方式

  • 用父进程捕获子进程的stdout,并且在python的父进程中新开线程实时读取子进程的输出并且将其输出
    def startCAN(recvport, sendport, motorFlag, use_power, use_gamePad, can_send_interval):
    # 构建命令列表,避免使用字符串格式化和 shell 操作符
    cmd = [
    ...
    ]

    process = subprocess.Popen(
    cmd,
    stdin=subprocess.DEVNULL, # 防止子进程读取主进程的输入
    stdout=subprocess.PIPE, # 可选:重定向子进程的输出
    stderr=subprocess.PIPE, # 可选:重定向子进程的错误输出
    text=True,
    bufsize=1,
    universal_newlines=True
    )
    def read_output():
    while True:
    line = process.stdout.readline()
    if line:
    print(line, end='')
    if process.poll() is not None:
    break # 如果子进程已终止,退出循环
    def read_err():
    while True:
    line = process.stderr.readline()
    if line:
    print(line, end='')
    if process.poll() is not None:
    break # 如果子进程已终止,退出循环
    output_thread = threading.Thread(target=read_output)
    output_thread.start()
    err_thread = threading.Thread(target=read_err)
    err_thread.start()
  • 但是有些时候子进程的输出无法实时的显示出来,只有当程序被结束的时候才会一起被显示
  • 这往往是因为子进程的输出被缓存了导致的
  • C语言可以使用
    // 设置stdout和stderr为无缓冲
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
  • 防止自己的输出被缓冲,从而实现实时输出到父进程的命令行再通过父进程输出到stdout