【问题标题】:read not blocking on named pipe在命名管道上读取不阻塞
【发布时间】:2010-08-12 11:13:53
【问题描述】:

我有以下 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 个字节,因此不确定为什么它不再阻塞。 'some string' 数据在另一端被正确接收。

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

【问题讨论】:

    标签: c linux named-pipes


    【解决方案1】:

    我在 gdb 中运行 C 代码程序,最初它在读取时会阻塞,但是一旦我调用 bash 脚本,C 代码就不再阻塞,它确实成功地从缓冲区读取数据,然后每次读取读取了 0 个字节,所以不确定为什么它不再阻塞。 'some string' 数据在另一端被正确接收。

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

    FIFO 的行为方式与 shell 管道逻辑兼容,例如:

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

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

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

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

    附:为您找到quite nice FIFO summary。检查第二页上的表格。

    【讨论】:

    • 非常感谢,没有意识到这一点。我应该在收到 EOF 后关闭先进先出,然后再重新打开它
    • @tech74:显然。 open() 分配新的文件描述符 - 旧的必须使用 close() 释放。在您重新打开 FIFO 以再次读取之前,写入器也会阻塞。
    【解决方案2】:

    您的 bash 脚本关闭管道,因此 C 获得“eof”条件

    【讨论】:

      【解决方案3】:

      我认为每次回显某些内容时都会编写侧面 shell 脚本来关闭管道。

      所以,写脚本需要打开管道,反复使用打开的描述符写东西,最后关闭打开的描述符。

      【讨论】:

        猜你喜欢
        • 2010-09-15
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-15
        相关资源
        最近更新 更多