我收到了“中断系统调用”的消息,并且真的不知道为什么说实话。我的作业是写服务器脚本谁使用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
答案 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 ... &
,产生另一行输出......