读不阻塞命名管道

问题描述:

我已经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个字节读取所以不知道为什么它不再阻塞。 '一些字符串'的数据在另一端正确接收。

我只需要坐在那里等待数据处理,然后回去等待更多

我运行在GDB的C代码程序,最初它在读取的块,但只要我调用bash脚本的C代码不再阻塞,它成功地从缓冲区中读取数据,然后每次读取时都有0个字节读取,所以不知道为什么它不再阻塞。 '一些字符串'的数据在另一端正确接收。

0表示EOF。只有在连接有读写的进程时才能读取或写入FIFO。当没有更多的作者(您的shell脚本终止)时,读者将通过返回EOF的read()得到通知。

FIFO的行为是那样要与壳管逻辑例如为:

$ mkfifo ./tmp1 
$ cat <input> ./tmp1 & 
$ cat <./tmp1> /dev/null 

兼容。如果read()不会EOF返回,第二cat将永远阻塞。

我只需要坐在那里等待数据处理,然后回去等待更多

在你的C程序必须重新open()的FIFO后read()返回EOF第一次。

P.S.为您找到quite nice FIFO summary。检查第二页上的表格。所以C是得到一个“EOF”条件

+0

非常感谢,没有意识到。在重新开放之前,我应该在收到EOF之后关闭fifo – tech74 2010-08-12 11:35:59

+0

@ tech74:显然。 'open()'分配新的文件描述符 - 旧的必须使用'close()'释放。作家将阻止,直到您重新打开FIFO再次读取。 – Dummy00001 2010-08-12 12:03:45

+1

+1链接! – 2012-11-05 11:31:36

您的bash脚本关闭管道。

因此,写脚本需要打开管道并重复使用打开的描述符来写入内容并最终关闭打开的描述符。

我觉得写边shell脚本关闭管道每当回声东西