为什么带有子流程的Python线程不能按预期工作?

时间:2017-10-11 13:02:37

标签: python subprocess python-multithreading

我有以下微妙的问题: Python代码启动两个线程,每个线程创建一个对exexutable的子进程调用(事实上用C语言编写)。第一个可执行文件传递参数10000,意味着在退出之前延迟10秒。与第二个可执行文件类似,但延迟时间为20秒。

我观察到,工人1和工人2同时进行打印输出,即20秒后,两次延误的时间越长。为什么worker1的wait()以某种方式被另一个更长的延迟“阻挡”了?无论我作为参数传递什么,两个打印输出都在两个时间的较长时间之后。

注意:这是一个用于演示目的的简化示例,而不是我正在处理的代码。无论如何,它与打印输出无关,在我的原始代码而不是打印中我做了一些更复杂的事情。

import subprocess
import threading
import time


def worker1():
    proc = subprocess.Popen(["../testapp1.exe", "10000"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    outs, errs = proc.communicate()
    ret = proc.wait()
    print("result worker1:%s ret:%d" % (outs, ret))
    print("done")


def worker2():
    proc = subprocess.Popen(["../testapp2.exe", "20000"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    outs, errs = proc.communicate()
    ret = proc.wait()
    print("result worker2:%s ret:%d" % (outs, ret))
    print("done")


job_thread1 = threading.Thread(target = worker1)
job_thread1.start()

job_thread2 = threading.Thread(target = worker2)
job_thread2.start()

job_thread1.join()
print ("after join1")
job_thread2.join()
print ("after join2")
# time.sleep(20000) original

可执行文件:

#include <string.h>
#include <windows.h>


int main(int argc, char *argv[])
{
  int count;
  //printf ("This program was called with \"%s\".\n",argv[0]);

  int sleep = 0;

  if (argc > 1)
  {
      for (count = 1; count < argc; count++)
      {
          if (count == 1)
          {
              sleep = atoi(argv[1]);
          }
          printf("\nargv[%d] = %s\n", count, argv[count]);
      }
  }
  else
  {
      printf("The command had no other arguments.\n");
  }

  int fin = sleep;
  for (int i=0; i<fin; i++)
  {
      for (int i2=0; i2<100; i2++);
  }
  //Sleep(sleep);

  return 0;
}

编辑:当我删除“沟通”时,它出于某种原因起作用。但在这种情况下,我无法获得该过程的输出......

def worker1():
    proc = subprocess.Popen(["../testapp1.exe", "10000"], shell=False, 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    # outs, errs = proc.communicate()
    ret = proc.wait()
    print("result worker1:%s ret:%d" % (outs, ret))
    print("done")

EDIT2:只使用wait(),我发现它在标记的标签上是阻塞的,管道的输出被读取...

def worker1():
    try:
        proc = subprocess.Popen(["../testapp.exe", "100000000"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        ret = proc.wait()
        xread = proc.stdout.read() ### !!!! BLOCKS
        print("xread:",xread)  
        sys.stdout.write("done-1")
        sys.stdout.flush()
    except ComError as e:
        print("got exception")
        raise e

0 个答案:

没有答案