【问题标题】:Running two executable in parallel with os.system() in Python?在 Python 中与 os.system() 并行运行两个可执行文件?
【发布时间】:2016-08-24 21:20:06
【问题描述】:

我希望同时运行两个可执行的a.exe和b.exe,一个接一个地调用。

当我尝试时,

os.system('a.exe')
#some code
os.system('b.exe')

b.exe 只有在我杀死 a.exe 后才能启动? 为什么会这样? 如何同时运行两者? (我需要做多线程吗?) 注意:我是Windows平台的

【问题讨论】:

    标签: python multithreading python-2.7 subprocess


    【解决方案1】:

    尝试将每个线程作为单独的线程运行:

    import thread
    
    thread.start_new_thread(os.system, ('a.exe',))
    thread.start_new_thread(os.system, ('b.exe',))
    

    【讨论】:

    • 这是我找到的最好的解决方案,因为它很简单。其他解决方案展示了生成 n 个进程的好方法,这对于生成一个异步进程而不阻塞程序的其余部分很有用。
    【解决方案2】:

    如果我们忽略异常,那么同时运行多个程序很简单:

    #!/usr/bin/env python
    import subprocess
    
    # start all programs
    processes = [subprocess.Popen(program) for program in ['a', 'b']]
    # wait
    for process in processes:
        process.wait()
    

    Python threading multiple bash subprocesses?

    如果您想在任何程序无法启动时停止之前启动的进程:

    #!/usr/bin/env python3
    from contextlib import ExitStack
    from subprocess import Popen
    
    
    def kill(process):
        if process.poll() is None:  # still running
            process.kill()
    
    with ExitStack() as stack:  # to clean up properly in case of exceptions
        processes = []
        for program in ['a', 'b']:
            processes.append(stack.enter_context(Popen(program)))  # start program
            stack.callback(kill, processes[-1])
        for process in processes:
            process.wait()
    

    【讨论】:

    • 酷。我使用 Popen(cmd,shell=True)
    【解决方案3】:

    您可能想尝试subprocess.Popen,这允许进程执行但不会阻塞。但是,在这种情况下,您必须考虑僵尸进程。

    【讨论】:

      【解决方案4】:

      您可以使用特定方式运行两个或多个命令或程序,例如 Python 的 threading 库。这里有一个关于它如何工作的广泛示例。

      import threading
      import time
      
      exitFlag = 0
      
      class myThread (threading.Thread):
          def __init__(self, threadID, name, counter):
              threading.Thread.__init__(self)
              self.threadID = threadID
              self.name = name
              self.counter = counter
          def run(self):
              print "Starting " + self.name
              print_time(self.name, self.counter, 5)
              print "Exiting " + self.name
      
      def print_time(threadName, delay, counter):
          while counter:
              if exitFlag:
                  threadName.exit()
              time.sleep(delay)
              print "%s: %s" % (threadName, time.ctime(time.time()))
              counter -= 1
      
      # Create new threads
      thread1 = myThread(1, "Thread-1", 1)
      thread2 = myThread(2, "Thread-2", 2)
      
      # Start new Threads
      thread1.start()
      thread2.start()
      
      print "Exiting Main Thread"
      

      那么,你的代码可能是这样的:

      import threading
      
      
      class myThread (threading.Thread):
          def __init__(self, command):
              threading.Thread.__init__(self)
              self.cmd = command
      
          def run(self):
              print "Starting " + self.cmd
              os.system(self.cmd)
              print "Exiting " + self.cmd
      
      lstCmd=["a.exe","b.exe","ping 192.168.0.10","some command"]
      
      # Create new threads
      thread1 = myThread(lstCmd[0])
      thread2 = myThread(lstCmd[1])
      thread3 = myThread(lstCmd[2])
      thread4 = myThread(lstCmd[3])
      
      # Start new Threads
      thread1.start()
      thread2.start()
      thread3.start()
      thread4.start()
      

      【讨论】:

        【解决方案5】:

        一个老问题,我自己是 python 新手,但如果您尝试与多个/不同的可执行文件并行调用,我发现“Popen”是合适的。

        from subprocess import Popen
        
        Popen('a.exe', shell=False)
        Popen('b.exe', shell=False)
        

        我发现它在我的用例中比“线程”(上面的@Lalo Ramírez 示例)更有用,因为 Popen(虽然一开始很棘手,尤其是 shell 参数)似乎更容易管理、检查和终止进程一旦启动(通过与 p1 或 p2 交互,如下例所示)。使用别名以提高可读性也可能很有用。

        from subprocess import Popen as new
        from time import sleep
        
        p1 = new('a.exe', shell=False)
        p2 = new('b.exe', shell=False)
        
        sleep(20)
        
        p1.terminate()
        p1.wait()
        

        有趣的是,“线程”正在模拟 Java 的线程功能,这可能更适合那些在 Java 中具有多线程经验的人。 “Popen”方法对我来说似乎是更简单的选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多