当我使用pipe时,我在select()处被封锁. 当我们在stdin上获取数据时,前select()将解除阻止

然后我将数据写入管道的写端,但select()无法识别管道的读FD上的任何数据. 所以它无限期地阻塞.

int    fd_pipe[2];
char   buf[20];
fd_set set;

pipe(fd_pipe);

FD_ZERO(&set);
FD_SET(fd_pipe[0], &set); // Pipe read fd
FD_SET(0         , &set); // stdin fd

select(fd_pipe[0]+1, &set, NULL, NULL, NULL); // I type 1 char + ENTER to get past this point

if (FD_ISSET(0, &set))
{
    read(0, buf, 20);          // Can confirm we do get here
    write(fd_pipe[1], buf, 1); // Lets put just one character in the pipe
}

select(fd_pipe[0]+1, &set, NULL, NULL, NULL); // <-- We get stuck here

if (FD_ISSET(fd_pipe[0], &set))
{
    char d;
    read(0, &d, 1);
    assert(d == buf[0]);
}

如果我在没有select()的情况下这样做,事情就会很好:

int fd_pipe[2];
pipe(fd_pipe);

char c = 'x';
write( fd_pipe[1], &c, 1);

c = 'a';
read( fd_pipe[0], &c, 1);

assert(c == 'x');

从更大的Angular 来看,我有一个多线程程序,它使用select()pipe()来模拟取消read()操作. 我用一个字符写入管道,目的是迫使select()返回,这样我就可以关闭操作,而不是try 发送信号来取消主FD上的阻塞read(). 但select()不会回来.

推荐答案

select函数修改您传递给它的集.当select返回时,集将仅包含活动描述符.

在您的情况下,仅会设置STDIN_FILENO,因此第二次调用select时将不会有fd_pipe[0].

解决方案实际上不是将管道重新添加到集合中并第二次调用select,而是只调用select 102:

FD_ZERO(&set);
FD_SET(fd_pipe[0], &set); // Pipe read fd
FD_SET(0         , &set); // stdin fd

select(fd_pipe[0]+1, &set, NULL, NULL, NULL); // I type 1 char + ENTER to get past this point

if (FD_ISSET(0, &set))
{
    read(0, buf, 20);          // Can confirm we do get here
    write(fd_pipe[1], buf, 1); // Lets put just one character in the pipe
}
else if (FD_ISSET(fd_pipe[0], &set))
{
    char d;
    read(fd_pipe[0], &d, 1);
    assert(d == buf[0]);
}

您还需要判断select实际上是returns.它可能会返回-1,这意味着存在错误.


如果您确实需要多次拨打select. 然后您需要重新归零/重新设置fd_set.

C++相关问答推荐

从STdin读写超过4096个字节

为什么下面的C代码会进入无限循环?

编译的时候g++通常会比GCC慢很多吗?

GCC预处理宏和#杂注GCC展开

SDL 2.0-从数组渲染纹理

我可以在C中声明不同长度数组的数组而不带变量名吗?

C中的指针增量和减量(*--*++p)

这个C程序在工作中途停止获取输入.我收到分段故障(核心转储).我还是不知道问题出在哪里

Boyer Moore算法的简单版本中的未定义行为

在C++中父进程和子进程中的TAILQ队列同步问题

为什么编译器不能简单地将数据从EDI转移到EAX?

错误:字符串在C中获得意外输出

为什么我的二叉树删除删除整个左部分的树?

用于计算位数和的递归C函数

如何使用WRITE()以指针地址的十六进制形式写入标准输出

当我将偏移量更改为任何非零值时,C中的mmap共享内存出现无效参数错误

如果类型是新的,offsetof是否与typeof一起工作?

在我的第一个C语言中观察到的错误';你好世界';程序

如何在Rust中处理C的longjmp情况?

malloc:损坏的顶部大小无法找出问题