2010-11-05 22 views
4

我有一堆我想並行執行的命令。這些命令幾乎完全相同。他們可以預計大約在同一時間,並可以完全獨立運行。他們可能看起來像:使用make來並行執行獨立任務

command -n 1 > log.1 
command -n 2 > log.2 
command -n 3 > log.3 
... 
command -n 4096 > log.4096 

我可以在一個shell腳本發動所有的人都在並行,但系統會試圖加載比嚴格意義上更以保持CPU(S)忙(每個任務需要100%一個核心直到完成)。這會導致磁盤崩潰,並使整個事情變得比較不貪心的執行方式慢。

最好的方法可能是保持執行n任務,其中n是可用內核的數量。

我非常希望不要重新發明輪子。這個問題已經在Unix make程序中解決(當與-j n選項一起使用時)。我想知道是否也許是可以寫入上述通用的Makefile的規則,從而避免了線性尺寸的Makefile那會是什麼樣子:

all: log.1 log.2 ... 
log.1: 
     command -n 1 > log.1 
log.2: 
     command -n 2 > log.2 
... 

如果最好的解決辦法是不使用make但另一個程序/實用程序,只要依賴關係合理(make在這方面非常好),我都會接受。

回答

3

pattern rules

的另一種方式,如果這就是爲什麼你需要make的唯一原因,是使用xargs-n-P選項。

+0

'回聲{1..1024} | xargs -n 1 -P 4 echo'給予'1 3 2 5 4 ...'(bash 3)似乎是我想要的。我當時沒有考慮這個問題,但我也可以爲'1'..''N/n','N/n + 1'..'2N/n'編寫'n'順序腳本。 。只要片段平均出來的時間(它不是給定的)。 – 2010-11-05 16:10:12

3

首先簡單的部分。作爲羅馬Cheplyaka指出,模式的規則是非常有用的:

LOGS = log.1 log.2 ... log.4096 
all: $(LOGS) 

log.%: 
    command -n $* > log.$* 

棘手的部分是創建一個列表,LOGS。 Make不擅長處理數字。最好的方法可能是調用shell。 (您可能需要調整這個腳本爲您shell-- shell腳本是不是我的最強的科目。)

NUM_LOGS = 4096 

LOGS = $(shell for ((i=1 ; i<=$(NUM_LOGS) ; ++i)) ; do echo log.$$i ; done) 
+0

你好,謝謝你的幫助。 Bash 3的模式爲「{1..1024}」,可能會被用於第二部分。 – 2010-11-05 16:14:29

3

xargs的-P是「標準」的方式來做到這一點。 注意取決於磁盤I/O,您可能想限制爲主軸而不是磁芯。 如果您確實想限制爲核心,請注意最近的coreutils中新的nproc命令。

+0

在我的情況下,如果需要的話,我可以將任務的所有輸入和輸出放入一個虛擬磁盤中,但是謝謝你向我介紹「主軸」的概念。 – 2010-11-05 16:25:29

4

下面是更便攜外殼代碼,不依賴於括號擴展:

日誌:= $(殼SEQ 1 1024)

注使用:=定義一個更有效的變量:簡單地擴大「風味」。