我有以下C代码从管道中读取然后应该阻塞但它永远不会阻塞
int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buf[100];
int bytes_read = 0;
memset (buf, '\0', sizeof(buf));
pipe_fd = open(FIFO_NAME, open_mode);
if (access(FIFO_NAME, F_OK) == -1)
{
res = mkfifo(FIFO_NAME, 0777);
if (res != 0)
{
fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME);
exit (EXIT_FAILURE);
}
}
for(;;)
{
do
{
res = read(pipe_fd, buf, sizeof(buf));
bytes_read += res;
}while (res > 0);
// process data then go back and block
............
}
它通过bash脚本中的某些代码发送一个简单的缓冲区,如'./test 1'
#!/bin/bash
pipe=/tmp/pipe
if [[ ! -p $pipe ]]; then
echo "Reader not running"
exit 1
fi
if [[ "$1" ]]; then
echo "some string" >$pipe
else
echo "q" >$pipe
fi
我在gdb中运行C代码程序并且最初它会阻止读取但是只要我调用bash脚本C代码不再阻塞,它就会成功读取来自 缓冲区,然后每次读取有0字节读取,所以不知道为什么它不再阻塞。 “一些字符串”数据在另一侧正确接收。
我只是需要它坐在那里等待数据处理它然后返回并等待更多
答案 0 :(得分:16)
我在gdb中运行C代码程序并且最初它会阻止读取但是一旦我调用bash脚本C代码不再阻塞,它就会成功地从缓冲区读取数据然后每次读取有0字节读取所以不知道为什么它不再阻塞。 “一些字符串”数据在另一侧正确接收。
0
表示EOF。只有当连接有进程才能读取和写入时,才能读取或写入FIFO。当没有更多的作者(你的shell脚本被终止)时,通过read()
返回EOF通知读者。
FIFO表现为与shell管道逻辑兼容的方式,例如:
$ mkfifo ./tmp1
$ cat < input > ./tmp1 &
$ cat < ./tmp1 > /dev/null
如果read()
不会返回EOF,则第二个cat
会永久阻止。
我只是需要它坐在那里等待数据处理它然后返回并等待更多
在你的C程序中,你必须在open()
第一次返回EOF后重新read()
。
P.S。找到了quite nice FIFO summary。检查第二页上的表格。
答案 1 :(得分:0)
你的bash脚本会关闭管道,以便C获得“eof”条件
答案 2 :(得分:0)
我认为写侧shell脚本每次回显时都会关闭管道。
因此,写脚本需要打开管道并重复使用opended描述符来写东西并最终关闭opended describepter。