读取在命名管道上不阻塞

发布于 2024-09-14 16:53:20 字数 1058 浏览 1 评论 0原文

我有以下 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 个字节,因此不确定为什么它不再阻塞。另一端正确接收到“某些字符串”数据。

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

i have the following bit of C code which reads from a pipe and then should block but it never blocks

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
    ............
}

It is sent a simple buffer by some code in a bash script like this './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

I run the C code program in gdb and initially it does block on the read but as soon as i call the bash script the C code no longer blocks , it does successfully read the data from
the buffer and then each time it reads there are 0 bytes read so not sure why its no longer blocking. The 'some string' data is correctly received at the other side.

I just need it to sit there waiting for data process it and then go back and wait for more

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诺曦 2024-09-21 16:53:21

我在 gdb 中运行 C 代码程序,最初它确实在读取时阻塞,但是一旦我调用 bash 脚本,C 代码就不再阻塞,它确实成功地从缓冲区读取数据,然后每次读取时已读取 0 个字节,因此不确定为什么它不再阻塞。对方正确接收到“some string”数据。

0 表示 EOF。仅当有进程连接到 FIFO 进行读写时,才能对 FIFO 进行读写。当不再有写入器(您的 shell 脚本终止)时,读取器会通过返回 EOF 的 read() 收到通知。

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

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

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

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

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

PS 为您找到了非常好的 FIFO 摘要。检查第二页上的表格。

I run the C code program in gdb and initially it does block on the read but as soon as i call the bash script the C code no longer blocks , it does successfully read the data from the buffer and then each time it reads there are 0 bytes read so not sure why its no longer blocking. The 'some string' data is correctly received at the other side.

0 means EOF. FIFO can be read or written only when there are processes connected to it for both reading and writing. When there are no more writers (your shell scripts terminated) readers are notified about that through read() returning the EOF.

FIFOs behave that way to be compatible with shell pipe logic e.g.:

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

If read() will not return EOF, the second cat would block forever.

I just need it to sit there waiting for data process it and then go back and wait for more

In your C program you have to reopen() the FIFO after read() returned the EOF first time.

P.S. Found quite nice FIFO summary for your. Check the table on the second page.

明天过后 2024-09-21 16:53:21

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

your bash script closes the pipe so the C is getting an "eof" condition

送你一个梦 2024-09-21 16:53:21

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

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

I think write side shell script close the pipe every time when echo something.

So, the write script need to open the pipe and repeatedly use the opended descriptor to write something and close the opended descripter finally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文