换个新网名 发表于 2021-5-21 03:39:48

subprocess.Popen()是否导致主例程暂停stdout?

这是我想做的事情:
在nix终端仿真器中,运行我的脚本。
调用subprocess.Popen()来生成许多进程,确保标准输出打印输出不会填满我的屏幕。
生成所有子进程后,我每秒都会对其进行轮询以收集返回码。收集完所有返回码后,我将继续打印摘要,以表明主要过程成功/失败的过程。每秒,我在屏幕上打印出一个进度点,以便在打印摘要之前,我知道主要进程正在运行。
我做了什么:
我在IDLE中开发了脚本,然后在IDLE中运行。在IDLE中,stdout没有发送到IDLE的Python shell,因此一切都按预期进行,在Raspberry pi上。
发生了什么:
一旦我开始在终端仿真器中运行相同的脚本,打印输出就会开始淹没我的终端。因此,我添加了stdout = subprocess.DEVNULL,从而抑制了打印输出。但是,同时,我的主要流程进度条的标准输出打印被暂停,直到所有流程结束并且所有进度点和摘要被立即打印出来。
我想知道如何在主流程中保持打印进度点而不被阻塞。
以下功能具有我描述的所有内容。第一个for循环产生所有子进程。然后,随后的while循环将继续轮询子进程并打印出进度点。'''Flash all firmware partitions for a new system'''
def flash_all(paras,flash_all_commands):
    processes=[]
    paras['return_code']=list(paras['name'])
    for Flash_ESP32_command in flash_all_commands:
      # print(Flash_ESP32_command)
      processes.append(subprocess.Popen(shlex.split(Flash_ESP32_command),stdout=subprocess.DEVNULL))
    while(True):
      i=0
      done=True
      for process in processes:
            return_code=process.poll()
            if return_code is None:
                done=False
                print('.',end='')
                break
                print("\n%s has not completed" %(paras['name']))
            else :
                paras['return_code']=return_code
            i=i+1
      if done: break
      time.sleep(1)
    i=0
    print()
    for jig_id in paras['id']:
      print("%s\t: %s" %(jig_id,'Success' if paras['return_code']==0 else 'Failure'))
      i=i+1

成章倾听 发表于 2021-5-22 23:14:30

我猜缓冲区在for循环的末尾被刷新。
您可以使用打印功能强制执行冲洗。

我们有着不一样的默契 发表于 2021-5-31 04:49:45

我认为在打印换行符时会刷新sys.stdout,因此会print('.')刷新stdout,但不会print('.', end='')
页: [1]
查看完整版本: subprocess.Popen()是否导致主例程暂停stdout?