gpt4 book ai didi

Linux fifo(命名管道)O_NONBLOCK 中断管道

转载 作者:太空宇宙 更新时间:2023-11-04 09:04:04 25 4
gpt4 key购买 nike

我一直在使用进程间通信用 C++ 为 linux 编写一个小程序。我在尝试以非阻塞方式读取一个进程并写入(阻塞)另一个进程时遇到问题。问题看起来像这样,当父级尝试使用 O_NONBLOCK(或 O_NDELAY)读取管道时,它从不读取单个字节,而当子级试图在管道上写入时, 它失败并发送 SIGPIPE broken pipe 信号。这是代码示例:

// Parent process
mkfifo(PROC_COPROC, 0666);

int fd_co = open(PROC_COPROC, O_RDONLY | O_NDELAY);
char c;
int n;
fcntl(fd_co,F_SETFL,0); //fix it
while ((n = read(fd_co, &c, 1)) > 0)
{
printf("%c", c);
}
close(fd_co);

// Child process
int fd = open(PROC_COPROC, O_WRONLY | O_APPEND);
if ( fd != -1 )
{
write( fd , "message\n" , 8); //Fails here if flag not set
}
else
printf("Ne peut pas ecrire sur le fifo\n");
close(fd);

我终于找到了解决这个问题的方法,方法是在非阻塞打开调用之后立即使用 fcntl(fd_co,F_SETFL,0);

看完man page ,我找不到任何(简单的)解释为什么如果我想读取非阻塞和写入阻塞,我应该重置文件描述符的标志。

有人有解释还是我做错了?

最佳答案

O_NDELAY 的“问题”是,当没有可用数据时,read 返回 -1 并将 errno 设置为 EAGAIN。所以,你必须测试read的返回值是否为-1和errno,然后再读取。

您的“修复”只是重置了 O_NDELAY,如果没有任何内容可从 FIFO 中读取,这会再次阻塞读取。

另见 read

RETURN VALUE
... On error, -1 is returned, and errno is set appropriately.

ERRORS
EAGAIN The file descriptor fd refers to a file other than a socket and has been marked nonblocking (O_NONBLOCK), and the read would block.
EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been marked nonblocking (O_NONBLOCK), and the read would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

您也可以考虑使用 select , 或 poll正如@BasileStarynkevitch 建议的那样,如果阻塞是您的问题。

关于Linux fifo(命名管道)O_NONBLOCK 中断管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14923525/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com