2012-11-10 27 views
1

我有很多工作要運行,比方說100.他們可以並行運行,但每個工作都佔用大量內存,所以我只能同時運行8個。總共運行N個作業,其中M個任意時間並行運行

我現在有這個shell腳本:

(
(python run.py $arg1 &) 
(python run.py $arg2 &) 
(python run.py $arg3 &) 
(python run.py $arg4 &) 
(python run.py $arg5 &) 
(python run.py $arg6 &) 
(python run.py $arg7 &) 
(python run.py $arg8 &) 
) 2>&1 | cat -u 

(
(python run.py $arg9 &) 
(python run.py $arg10 &) 
(python run.py $arg11 &) 
(python run.py $arg12 &) 
(python run.py $arg13 &) 
(python run.py $arg14 &) 
(python run.py $arg15 &) 
(python run.py $arg16 &) 
) 2>&1 | cat -u 

... 

這有運行首批8的效果,而當他們已經全部結束,它開始的8下一批次的問題是,每個作業的運行時間並不是一成不變的,而有些則在其他人之前完成,因此,對於每批8個工作要完成的權重並不是最優的,因爲我正在等待8個工作中最慢的工作。

相反,我想有一個腳本(殼或Python),將運行我所有的100個職位,在任何給定的時間讓他們的8並行,以達到最佳效率。

任何關於實現這一點的想法?

+0

'cat -u'應該做什麼?根據[手冊頁](http://unixhelp.ed.ac.uk/CGI/man-cgi?cat)-u被忽略。 –

+1

@NickODell TBH我從某處複製了這個腳本,所以我不確定。我的男人顯示了不同的東西:「-u禁用輸出緩衝。」 – Greystache

回答

4

您可以編寫自己的小調度程序,將它們提供給使用其當前任務完成的處理程序;但在我們的中心we strongly recommend使用gnu parallel,它已經實現了類似xargs的語法。

因此,舉例來說,如上,你可以做

parallel --max-procs 8 <<EOF 
    python run.py $arg1 
    python run.py $arg2 
    python run.py $arg3 
    .. 
EOF 

或者,如果你在一個文件中有你的參數列表,你可以不喜歡

cat args.list | parallel --max-procs 8 python run.py 
+0

謝謝,這似乎是一個很好的解決方案! – Greystache

3

根據您的需要,您可以使用許多工具。最簡單的可能是使用GNU parallelmake可以與其-j開關同時運行任務。如果您嘗試運行的任務更加複雜和多樣化,那麼真正的排隊系統可能會有所幫助,例如, Dr. Queue。還有更多的工具,GNU parallel's man page很好地列出它們。

2

這在我看來,您正在尋找multiprocessing模塊,特別是multiprocessing.Pool

如果我這樣做了,我會給run.py所有不同的參數組,然後把你在頂層做的事情放在main(args)函數的run.py中,然後使用Pool的map方法調用該方法覆蓋所有不同的參數集。

它可能是這個樣子:

import multiprocessing 

def main(args): 
    # Here's where you would do what you usually do with the arguments 

pool = multiprocessing.Pool(processes=8) 
pool.map(main, sys.argv[1:], chunksize=1) 
pool.close() 
pool.join() 

注意,這裏假設每次運行參數可在一個串(並由此sys.argv一個條目)舉行。