2012-12-23 23 views
1

所以,讓我們從頭開始:2進程1管道溝通,對吧?沒有!因爲溝通阻塞,人們會等待另一個。我們需要通過不同渠道從第二個過程獲得結果。雖然看起來多餘,但並非如此。2個進程之間使用的命名管道(第2號)有什麼問題?

讓我們稍微改變一下:2進程2管道,你可以調用一個進程的服務器和另一個客戶端。一個管道將作業發送到客戶端,另一個管道用於將客戶端的結果收集到服務器。

爲方便起見,我們呼籲各管與被用於讀取這樣的進程名,倫敦讀倫敦管等。這就是管道和過程的示意圖:

london ----writes madrid pipe--------> 
london <----reads london pipe------ | 
           ^| 
            | | 
madrid ----writes london pipe-----> v 
madrid <----reads madrid pipe--------- 

讓我們用「倫敦」爲服務器和「馬德里」作爲客戶端:服務器負責結束無限循環。

這是解決方案:

#!/bin/bash 
shopt -u failglob 
shopt -s extglob nullglob dotglob 

DIR=$(cd "$(dirname "$0")" && pwd) 

function london(){ 
    local i message answer london madrid 
    london=london_$RANDOM.$RANDOM.$RANDOM.$$ 
    madrid=madrid_$RANDOM.$RANDOM.$RANDOM.$$ 
    cd $DIR 
    mkfifo $london 
    mkfifo $madrid 
    (madrid $madrid $london) & 
    echo "parent id: $$, child id: $!" 
    i=0 
    #a mesterious situation: sometimes '3< $london' just breaks it (?!) 
    exec 3<> $london 
    exec 4> $madrid 

    while true; do 

     message="Greetings from London!($i)" 
     echo "$message" >&4 

     read -r answer <&3 
     echo 'London says:> '"$answer" #>& /dev/stdout 
     ((i++)) 

     if [[ i -gt 1 ]]; then 
     echo 'quit' >&4 
     break 
     fi 
    done 

    wait 
    cd "$DIR" 
    rm -rf $london 
    rm -rf $madrid 
} 

function madrid(){ 
    local i message answer madrid london 
    madrid=$1 
    london=$2 
    cd $DIR 
    i=0 
    exec 3> $london 
    exec 4< $madrid 
    while true; do 

     read -r answer <&4 
     echo 'Madrid says:> '"$answer" #>& /dev/stdout 

     message="Greetings from Madrid!($i)" 
     echo "$message" >&3 
     ((i++)) 

     if [[ $answer = 'quit' ]]; then 
     break 
     fi 
    done 
} 

london 

在功能 '倫敦' 有剛

exec 3<> $london 

如果你改變這

exec 3< $london 

,因爲它應該再發表評論(!)那麼,我面臨着我的程序一再停頓的情況! 經過從<>到<的一些更改,反之亦然,問題消除了,我無法再現它!我使用的是Ubuntu系統,所以如果有人可以用他/她的系統測試這個程序並發表一些評論,它會受到歡迎。

回答

0

這裏程序只有在後臺啓動時纔會停止,因爲tty輸出。當您可以重現問題時,您應該已將strace附加到第一個過程。