Запускать несколько подпроцессов в цикле foreach? Один за раз? - PullRequest
3 голосов
/ 26 января 2012

Я создаю скрипт на python, который запускает rsync с использованием подпроцесса, а затем получает стандартный вывод и распечатывает его.Скрипт запускает несколько баз процессов rsync в файле conf, используя этот код:

for share in shares.split(', '):
  username = parser.get(share, 'username')
  sharename = parser.get(share, 'name')
  local = parser.get(share, 'local')
  remote = parser.get(share, 'remote')
  domain = parser.get(share, 'domain')
  remotedir = username+"@"+domain+":"+remote
  rsynclog = home + "/.bareshare/"+share+"rsync.log"
  os.system("cp "+rsynclog+" "+rsynclog+".1 && rm "+rsynclog) # MOve and remove old log
  rsync="rsync --bwlimit="+upload+" --stats --progress -azvv -e ssh "+local+" "+username+"@"+domain+":"+remote+" --log-file="+rsynclog+" &"
  # Run rsync of each share
  #         os.system(rsync) 
  self.rsyncRun = subprocess.Popen(["rsync","--bwlimit="+upload,"--stats","--progress","-azvv","-e","ssh",local,remotedir,"--log-file="+rsynclog], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

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

Мой полный сценарий можно найти здесь: https://github.com/danielholm/BareShare/blob/master/bareshare.py

Редактировать: И как я могу сделать себя.rsyncRun умереть, когда закончите?Когда rsync завершает работу со всеми файлами, кажется, что он продолжается, хотя и не должен этого делать.

1 Ответ

4 голосов
/ 26 января 2012

Calling

self.rsyncRun.communicate()

блокирует основной процесс до тех пор, пока процесс rsyncRun не завершится.


Если вы не хотите, чтобы основной процесс блокировался, создайте поток для обработки вызовов subprocess.Popen:

import threading

def worker():
    for share in shares.split(', '):
        ...
        rsyncRun = subprocess.Popen(...)
        out, err = rsyncRun.communicate()

t = threading.Thread(target = worker)
t.daemon = True
t.start()
t.join()
...