2011-11-30 99 views
1

我一直百思不得其解這個現在整整一夜......蟒蛇平行POPEN

makeflags = ['--prefix=/usr','--libdir=/usr/lib'] 
rootdir='/tmp/project' 
ps = set() 

def configModule(m): 
    print m 
    return Popen(["./autogen.sh"] + makeflags, cwd=rootdir+"/"+m) 

for module in ['mod1','mod2','mod3' ... 'mod10']: 
    ps.add(configModule(module)) 

os.wait() 

我期待它會啓動10個進程和並行執行./autogen.sh。但是,我觀察到的是,第一個configModule似乎在函數被調用後立即退出。我只看到「print m」語句,但不是「mod1」中的./autogen.sh的實際輸出。但是,在mod4之後,代碼開始並行運行。我可以看到CPU利用率很高,並且輸出已經在不同的模塊文件夾中生成。

任何想法爲什麼前幾個模塊不產生./autogen.sh結果?

P.S.如果我以串行方式運行此代碼(即使用subprocess.call而不是Popen),它可以正常工作。

+0

我還試圖用多模塊,不幸的是,我可以克服unpickle問題,因爲我試圖啓動的進程池的一類... – Patrick

+0

我認爲這是一個複製/粘貼錯誤,但是不應該將'm'傳遞給'Popen'調用而不是'module'? – jro

+0

@jro是啊,好眼睛!我修復了錯字。 – Patrick

回答

1

您的代碼適用於我,並應啓動所有進程。你沒有給我們太多的工作:什麼行爲不同?

您不會將輸出重定向到您粘貼的代碼中,因此您可能會看到子視圖的流stderr。有一件事是:

os.wait() 

...只會等待1個進程。您可能想要使用Popen的返回值,並在每個子進程上調用waitcommunicate。然後,您可以另外使用返回值,以確保他們都成功地死去:

# Instead of os.wait(): 
for p in ps: 
    p.wait() 
    print 'A process returned:', p.returncode 

希望,他們都應該是0,如果一切正在恢復正常。

+0

如果3個數據流中沒有一個被重定向到PIPE,那麼'communic()'就沒有用處。 'wait()'應該在這裏就足夠了... – glglgl

+0

啊,我想我可能知道現在發生了什麼......因爲這是一個非阻塞的調用,所以在任務完成之前我看到了「print m」。 ./autogen.sh可能已經排隊並仍在使用它。我會再等一會兒,看看所有文件夾是否都正常。 – Patrick

+0

@glglgl:在這種情況下,'communic'變成等同於'wait'。儘管如此。 – Thanatos

1

與DA虛擬系統調用工程的similiarly建立程序按預期:

from subprocess import * 

makeflags = ['--prefix=/usr','--libdir=/usr/lib'] 
rootdir='/tmp/project' 
ps = dict() 

def configModule(m): 
    print m 
    p = Popen("echo start %s; sleep %d; echo finish %s" % (m, 10-m, m), shell=True) 
    #p.m = m 
    return p 

for module in range(10): 
    ps[configModule(module)] = module 

while ps: 
    done = set() 
    for p in ps: 
     s = p.poll() 
     if s is not None: 
      print "Module %d: %d" % (ps[p], s) 
      done.add(p) 
    for p in done: 
     del ps[p] 
#os.wait() 

你肯定輸出真正缺少的,或只是延遲?

BTW:

for module in ('mod%d' % i for i in range(1, 11)): 

是更優雅...