1

那么,让我们从头开始:2 个进程 1 个管道进行通信,对吧?不!因为通信被阻塞,一个等待另一个。我们需要通过不同渠道获得第二个过程的结果。虽然它看起来是多余的,但它不是。

让我们稍微改变一下:2 个进程 2 个管道,您可以将一个进程称为服务器,另一个进程称为客户端。一个管道将作业发送到客户端,另一个用于将结果从客户端收集到服务器。

为方便起见,我们使用用于读取的进程名称来调用每个管道,london 读取 london 管道,依此类推。这是管道和流程的示意图:

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 系统,所以如果有人可以用他/她的系统测试该程序并发表一些评论,它将受到欢迎。

4

1 回答 1

0

这里程序只有在后台启动时才会停止,因为 tty 输出。当您可以重现问题时,您应该附加strace到第一个过程。

于 2013-11-19T09:20:28.643 回答