bash系统调用中断

时间:2016-12-08 16:32:42

标签: bash fifo

我收到了“中断系统调用”的消息,并且真的不知道为什么说实话。我的作业是写服务器脚本谁使用fifo与客户端脚本进行通信,基本上它工作,但我不知道如何摆脱这个消息。对任何建议都会感激。

我的服务器脚本:

#!/bin/bash

server=serwerfifo

if [[ "$1" ]]; then
    if [[ ! -p $1 ]]; then
        echo "Reader(klient) not running"
    else
        echo $(expr $2 + $2) > $1 &
    fi
else
    trap "" SIGHUP SIGTERM SIGCHLD
    trap "exit 0" SIGUSR1

    if [[ ! -p $server ]]; then
        mkfifo $server
    fi

    while true
    do
        if read line < $server; then
            $0 $line &
        fi
    done
fi

解释程序丰富此行时会显示消息:

if read line < $server; then

2 个答案:

答案 0 :(得分:1)

关于EINTR - 您通过重复重新打开FIFO,使您的代码不必要地容易出现竞争条件。不要经常这样做 - 在作者关闭之前使用一个句柄(因此你得到一个EOF)。

while :; do # if we hit end-of-FIFO, then loop around and try to reopen
  while read -r line; do
    "$0" "$line" &
  done < "$server"
done

请注意< "$server" <循环上的,而不是read上的{strong},所以如果您的作者写了多行,那么这些多行将被读取读者在关闭FIFO之前。

另一个相关的事情是你使用后台进程使事件异步(因此它们的顺序是非确定性的)。你真的可以获得一个完全合法中断的系统调用,特别是当你在难以预测的时间发生打开和关闭操作时:一个UNIX内核允许告诉userland它需要重试它正在做的事情(并且另一次尝试将成功)。这不是错误,这是合法且允许的结果。

答案 1 :(得分:0)

(取代之前的评论。)

首先,

$0 $line & 

应该是

"$0" "$server" "$line" &

因为生产者代码期望$1是FIFO的名称。双引号是指$0$server$line中的任何内容包含空格或其他特殊(对于bash)字符。

在cygwin上,我能够通过在一个终端中手动运行foo.sh并在单独的终端中foo.sh serwerfifo 4来测试代码。但是,我无法重现“中断的系统调用”。但是,我确实在foo.sh终端中获得了无限循环的双倍值。这是意图吗?原因是$0 ... &的每次调用都会为read生成另一行输出,然后消费者再次调用$0 ... &,产生另一行输出......