2016-09-09 2 views
0

Я пытаюсь удаленно выполнить команду на неизвестном количестве хостов (может быть где угодно от одного узла до сотен) в сценарии Python. Простой способ сделать это состоит в следующем, но, очевидно, он может получить до смешного много времени с большим количеством хостов:Python - как удаленно выполнять процессы параллельно и получать их выходные данные

listOfOutputs = [] 
for host in listOfHosts: 
    output = subprocess.Popen(shlex.split("ssh %s '<command>'" % host), stdout = subprocess.PIPE).communicate()[0] 
    listOfOutputs.append(output) 

Есть ли способ сделать это то же самое, но есть команды удаленно выполнять параллельно, так это не занимает столько времени?

ответ

0

Вы должны запускать свои Popen.subprocess звонки каждый в отдельном потоке, чтобы вы могли запускать столько, сколько хотите, не блокируя свою основную программу.

Я сделал небольшой пример, создавая столько потоков, сколько будет хостов. Ничего страшного, так как потоки будут в основном ждать ответа хозяина (иначе пулы потоков были бы лучше)

В моем примере у меня есть 3 хоста, и я выполняю ping на каждом из них. Выходы сохраняются в потокобезопасном списке выходов и печатаются в конце:

import threading 
import subprocess 

listOfOutputs=[] 

lock = threading.Lock() 

def run_command(args): 
    p = subprocess.Popen(["ping","-n","1",args],stdout = subprocess.PIPE) 
    output,err = p.communicate() 
    lock.acquire() # listOfOutputs is thread-safe now 
    listOfOutputs.append(args+": "+output) 
    lock.release() 

threads=[] 
listOfHosts = ['host1','host2','host3'] 
for host in listOfHosts: 
    t = threading.Thread(target=run_command,args=[host]) 
    t.start()   # start in background 
    threads.append(t) # store thread object for future join operation 


[t.join() for t in threads] # wait for all threads to finish 

# print results 
for o in listOfOutputs: 
    print(o) 
    print("-"*50) 
Смежные вопросы