2017-04-17 175 views
1

所以我有一個while循環遍歷包含名稱的文本文件,然後在列表上執行後臺進程。這一切都很好,但當它結束時,我需要按Ctrl-C。一旦所有進程完成後,我如何執行SIGINT,因此我不必ctrl-c?殺死在while循環後臺進程中創建的PID

我需要在每個單獨的過程中完成嗎?或者我可以通過使用像睡覺這樣的循環來做到這一點?

這是我目前有的,但不是很有效。

while read BAR; do foo $BAR & done < bars.txt; pid=$!; wait; kill pid

回答

1

現在你只收集最後 PID,所有你的後臺進程不會的PID。

如果您收集的PID,您可以單獨等待他們 - 它可以讓你檢查單個作業是否失敗,看到它們中的哪一個實際上並沒有完成:

pids=() 
while read bar; do 
    foo "$bar" & pids+=("$!") 
done < bars.txt 

for pid in "${pids[@]}"; do 
    echo "Checking exit status of $pid..." 
    if wait "$pid"; then 
    echo "$pid succeeded!" 
    else 
    echo "$pid failed!" 
    fi 
done 

如果你想跟蹤哪些具體值是成功還是失敗處理,你可以做得更好(使用bash 4.0或更高版本):

declare -A pids=() 
while read -r bar; do 
    foo "$bar" & pids[$!]="$bar" 
done < bars.txt 

for pid in "${!pids[@]}"; do 
    bar=${pids[$pid]} 
    echo "Checking exit status of $pid (processing value $bar)..." 
    if wait "$pid"; then 
    echo "$pid (for $bar) succeeded!" 
    else 
    echo "$pid (for $bar) failed!" 
    fi 
done 

在上述任何一種情況下,wait的每個調用都負責在相應的PID退出後返回。因此,當所有後臺任務都退出時,腳本將自行退出。


最後,你的孩子退出,你可以建立,是以PID列表的優勢的信號處理程序:

shutdown() { kill "${pids[@]}"; } # or "${!pids[@]}" for the second example 
trap shutdown 0 
+0

不,我應該這樣做,但是反正有做在一個「襯」,所以我沒有執行一份文件?像我可以把等待在循環中然後殺死PID?或者這只是讓它再次同步? –

+0

備份一下 - 爲什麼「殺死」呢?當我讀到這個問題時,你的後臺進程會自行退出,唯一的問題是調用它們的腳本不在退出......對嗎? –

+0

如果你想要一個處理並行進程的單線程,順便說一句,你可能更好的是'xargs -P'或者GNU parallel。例如,一次最多可運行16個進程:'xargs -d $'\ n'-P 16 foo

0

如果你真的想要一個班輪,你可以圍繞以下邏輯構建它(格式化以提高可讀性)。

while -r read BAR 
do 
    foo "$BAR" & 
done < bars.txt 
wait 

這將等待所有後臺任務完成(包括執行此命令之前啓動的任何後臺任務)。這有點粗糙(CharlesDuffy提出了一個解決方案,可以更好地跟蹤任務),但它有足夠短的單線程的可疑優勢。

while -r read BAR ; do foo "$BAR" & done < bars.txt ; wait 

殺作業啓動他們之後(我不清楚你爲什麼會想這樣做),你也許可以做這樣的事情:

while -r read BAR ; do foo "$BAR" & done < bars.txt ; kill $(jobs -p) 

再次,這將標誌着所有後臺工作,不僅僅是你剛剛發佈的工作。

+0

不幸的是,我的後臺進程不能自行退出 –

1

隨着GNU並行它看起來像這樣:

parallel -j0 foo {} < bars.txt 
echo $? jobs failed 

如果你離開了-j0它將運行每個CPU核心一個作業。

如果您需要確切的作業失敗知道,你可以使用一個joblog:

parallel --joblog jl -j0 foo {} < bars.txt 
cat jl 

它還確保不同作業中的輸出不會混合在一起,因此,如果您使用的輸出,保證您你不會從兩個不同的工作中獲得半條命。

GNU Parallel是一個通用的並行程序,可以很容易地在同一臺機器上或在您擁有ssh訪問權限的多臺機器上並行運行作業。

如果你想在4個CPU上運行32個不同的工作崗位,並行化直接的方式是在每個CPU上運行8個作業:

Simple scheduling

GNU並行,而不是產生一個新的進程時,一個完成 - 保持CPU的活躍,從而節省了時間:

GNU Parallel scheduling

安裝

您應該在您的軟件包管理器中安裝GNU Parallel,但是如果您的發行版沒有打包GNU Parallel,則可以執行個人安裝,但不需要root訪問權限。它可以在10秒內通過這樣來完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

對於其他安裝選項見http://git.savannah.gnu.org/cgit/parallel.git/tree/README

瞭解更多

查看更多的例子:http://www.gnu.org/software/parallel/man.html

觀看介紹視頻: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

走過t他教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

訂閱郵件列表,以獲得支持:https://lists.gnu.org/mailman/listinfo/parallel