【问题标题】:Python3 parallel processes with their own timeouts具有自己超时的 Python3 并行进程
【发布时间】:2020-03-27 16:38:24
【问题描述】:

我有一个要求,我必须启动多个应用程序,获取它们的每个 stdout、stderr 并且这些应用程序可以无限运行。这些进程不交换/共享数据并且彼此独立。要进行可变压力测试,它们的超时时间可能不同。

For eg: 
app1 -> 70sec
app2 -> 30sec
.
.
appN -> 20sec

如果这些是具有一个共同超时的多个应用程序,我会将其包装在一个定时的 while 循环中并最终终止所有进程。

以下是我认为应该可行的一些方法:

  1. 每个应用程序都有一个计时器线程,它读取标准输出并在它过期后立即终止进程。进程在线程内启动
  2. 一个计时器线程循环遍历每个进程的 pid/process_objects:end_time 字典,并在其 end_time >= 当前时间时终止该进程

我曾尝试使用 asyncio gather,但它并不能完全满足我的需求,而且我在 Windows 上遇到了一些问题。

我还有其他方法可以使用吗?

【问题讨论】:

    标签: python multiprocessing python-3.7


    【解决方案1】:

    第二个选项非常适合生产。有一个控制循环,您可以在其中轮询进程以完成并在它们超时时终止它们

    【讨论】:

      【解决方案2】:

      这是第二种方法的代码(扩展 https://stackoverflow.com/a/9745864/286990)。

      #!/usr/bin/env python
      import io
      import os
      import sys
      from subprocess import Popen
      import threading
      import time
      import psutil
      
      def proc_monitor_thread(proc_dict):
          while proc_dict != {}:
              for k,v in list(proc_dict.items()):
                  if time.time() > v:
                      print("killing " + str(k))
                      m = psutil.Process(k)
                      m.kill()
                      del proc_dict[k]
              time.sleep(2)
      
      pros = {} 
      
      ON_POSIX = 'posix' in sys.builtin_module_names
      
      # create a pipe to get data
      input_fd, output_fd = os.pipe()
      
      # start several subprocesses
      st_time = time.time()
      for i in ["www.google.com", "www.amd.com", "www.wix.com"]:
          proc = Popen(["ping", "-t", str(i)], stdout=output_fd,
                         close_fds=ON_POSIX) # close input_fd in children
      
          if "google" in i:
              pros[proc.pid] = time.time() + 5
          elif "amd" in i:
              pros[proc.pid] = time.time() + 8
          else:
              pros[proc.pid] = time.time() + 10
      
      os.close(output_fd)
      x = threading.Thread(target=proc_monitor_thread, args=(pros,))
      x.start()
      
      # read output line by line as soon as it is available
      with io.open(input_fd, 'r', buffering=1) as file:
          for line in file:
              print(line, end='')
      #
      
      print("End")
      x.join()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-01
        • 1970-01-01
        • 2019-03-28
        • 2014-05-17
        • 2019-04-07
        • 1970-01-01
        相关资源
        最近更新 更多