Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一次运行x个命令_Python_Subprocess_Popen - Fatal编程技术网

Python 一次运行x个命令

Python 一次运行x个命令,python,subprocess,popen,Python,Subprocess,Popen,我必须在循环中运行200个文件的程序 现在我让他们像这样运行: for combo in it.combinations(files, 2): cmd = ["command", combo[0], combo[1]] subprocess.Popen(cmd) import socket import threading import Queue import subprocess class IPThread(threading.Thread): def __in

我必须在循环中运行200个文件的程序

现在我让他们像这样运行:

for combo in it.combinations(files, 2):
    cmd = ["command", combo[0], combo[1]]
    subprocess.Popen(cmd)
import socket
import threading
import Queue
import subprocess

class IPThread(threading.Thread):
    def __init__(self, queue, num):
        super(IPThread, self).__init__()
        self.queue = queue
        self.num = num
    def run(self):
        while True:
            try:
                args = self.queue.get_nowait()
                cmd = ["echo"] + [str(i) for i in args]
                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                out, err = p.communicate()
                print out
            except Queue.Empty:
                # Nothing left in the Queue -- we are done
                print "Queue %d done" % self.num
                break
            except Exception as err:
                # Handle exception
                print err
            self.queue.task_done()

def create_threads(q, size):
    for i in range(size):
        thread = IPThread(q, i)
        thread.setDaemon(True)
        thread.start()
    q.join()

def fill_queue(q):
    # Call q.put(args) in a loop to populate Queue with arguments
    from itertools import permutations
    x = list(range(20))
    for arg1, arg2 in permutations(x, 2):
        q.put([arg1, arg2])
    print q.qsize()

def main():
    q = Queue.Queue()
    fill_queue(q)
    create_threads(q, 60)
    print "Done"

if __name__ == '__main__':
    main()

我想一次只运行60次,这样不会使计算机崩溃,该命令相当于处理器密集型。在60个进程运行后暂停循环,然后在其中一个进程完成后重新启动循环,以便始终有60个进程在运行的最佳方式是什么?

您希望这样:

for combo in it.combinations(files, 2):
    cmd = ["command", combo[0], combo[1]]
    subprocess.Popen(cmd)
import socket
import threading
import Queue
import subprocess

class IPThread(threading.Thread):
    def __init__(self, queue, num):
        super(IPThread, self).__init__()
        self.queue = queue
        self.num = num
    def run(self):
        while True:
            try:
                args = self.queue.get_nowait()
                cmd = ["echo"] + [str(i) for i in args]
                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                out, err = p.communicate()
                print out
            except Queue.Empty:
                # Nothing left in the Queue -- we are done
                print "Queue %d done" % self.num
                break
            except Exception as err:
                # Handle exception
                print err
            self.queue.task_done()

def create_threads(q, size):
    for i in range(size):
        thread = IPThread(q, i)
        thread.setDaemon(True)
        thread.start()
    q.join()

def fill_queue(q):
    # Call q.put(args) in a loop to populate Queue with arguments
    from itertools import permutations
    x = list(range(20))
    for arg1, arg2 in permutations(x, 2):
        q.put([arg1, arg2])
    print q.qsize()

def main():
    q = Queue.Queue()
    fill_queue(q)
    create_threads(q, 60)
    print "Done"

if __name__ == '__main__':
    main()
创建要处理的事情的队列。专门化线程派生类。旋转你的线。等待他们完成


您可以看出这些任务是并发运行的,因为它们的输出相互干扰。这是一个特色

你可以做一些非常简单的事情,比如:

from time import sleep

count = 0
for combo in it.combinations(files, 2):
    while count < 60:
        cmd = ["command", combo[0], combo[1]]
        subprocess.Popen(cmd)
        count = count + 1
        if subprocess_is_done:
            count = count - 1
    sleep(5)
从时间导入睡眠
计数=0
对于it.combo中的combo组合(文件,2):
当计数小于60时:
cmd=[“命令”,组合[0],组合[1]]
子进程Popen(cmd)
计数=计数+1
如果子流程完成:
计数=计数-1
睡眠(5)
显然,您需要弄清楚如何从命令中获取
子流程

据我所知,这适用于普通情况,但不知道您要运行什么…

这可能会有帮助:

import itertools as it
import time
import subprocess

files = range(5)
max_load = 3
sleep_interval = 0.5

pid_list = []
for combo in it.combinations(files, 2):
  # Random command that takes time
  cmd = ['sleep', str(combo[0]+combo[1])]

  # Launch and record this command
  print "Launching: ", cmd
  pid = subprocess.Popen(cmd)
  pid_list.append(pid)

  # Deal with condtion of exceeding maximum load
  while len(filter(lambda x: x.poll() is None, pid_list)) >= max_load:
    time.sleep(sleep_interval)

:它显示多处理.Pool、concurrent.futures、threading+基于队列的解决方案。

签出threading.Thread,您可以创建60个线程,然后让它们从列表中提取命令,直到其为空(然后让它们退出)@maxk。在一般情况下,使用python线程不会提高性能。OP已经包含了使用subprocess模块的代码,建议在python中并行执行。它不会提高性能,但更具可定制性,编写自己的线程子类的能力为您提供了更多解决此类问题的选项。只是一个想法though@Wilduck-在这种情况下,线程确实可以提高性能。在分派新进程之前,必须等待进程完成。每个进程执行p.communicate()或p.wait()的线程是一个非常好的解决方案。我认为max k是对的,这是线程池的一个很好的用途。我一直在考虑这些问题,但我不知道如何判断子进程何时完成。可能是wait()或poll(),但不确定它们在此循环中如何工作。您需要记录所有当前正在运行的进程,并使用
.poll()
确定它们的状态。此示例不等待进程完成,也不处理进程因其管道已满而生成输出并暂停的可能性。如前所述,它将同时启动所有流程。这不是海报想要的。它一次最多运行60个进程,每创建一个线程一个。它不会一次启动所有进程。关于填充输出缓冲区,您是对的。这是海报的主要部分。例如,我不知道队列中应该是什么,所以我只使用整数。我不知道OP的输出会占用多大的缓冲区,所以我只能猜测要使用的
bufsize
。但这是问题的主要部分,对吧--同时运行多个进程?它已被编辑为包含p.communicate(),因此现在工作正常。+1好的,让我们开始吧:这是一个合理的答案。我会投这一票。