在管道上使用时,stdin上的select()行为

在管道上使用时,stdin上的select()行为,select,pipe,stdin,Select,Pipe,Stdin,我试图理解在stdin上使用select()时,当它从管道接收数据时,对其行为的观察 基本上,我有一个简单的C程序,使用以下代码: 你好,c: 但是,如果按如下方式使用该程序,则该程序永远不会达到显示“无数据”的状态。而是重复显示最后一个字符“c” echo -n abc | ./hello 我对这一观察结果感到有点困惑,如果您能帮助我理解观察到的行为,我将不胜感激。问题是,您的程序在从STDIN\u FILENO描述符读取时没有检测到文件结束情况。在echo写入c字符后,它将关闭其管道末端,

我试图理解在stdin上使用select()时,当它从管道接收数据时,对其行为的观察

基本上,我有一个简单的C程序,使用以下代码: 你好,c:

但是,如果按如下方式使用该程序,则该程序永远不会达到显示“无数据”的状态。而是重复显示最后一个字符“c”

echo -n abc | ./hello

我对这一观察结果感到有点困惑,如果您能帮助我理解观察到的行为,我将不胜感激。

问题是,您的程序在从
STDIN\u FILENO
描述符读取时没有检测到文件结束情况。在
echo
写入
c
字符后,它将关闭其管道末端,这将导致程序中的
select
立即返回,而
read
返回0,表示该描述符将不再提供任何数据。你的程序没有检测到这种情况。相反,它只调用
write
,使用上次成功的
read
在缓冲区中留下的任何字符,然后重复循环


若要修复,请在(n==0)中断时执行
阅读之后

谢谢,现在它有意义了。这是否也意味着当fd引用一个关闭的文件时,select()将不会返回错误条件(-1)?如果任何描述符引用一个关闭的文件,select将返回-1。这不会发生在您的程序中,因为您从未关闭程序的STDIN描述符。如果
close(STDIN\u FILENO)
read
返回0时,您保持在循环中,那么您将在下一次
select
调用中看到-1。(在
echo
程序中对管道的写入端执行的
close
不会关闭程序中管道的读取端。它只会导致程序中读取的
出现“文件结束”指示。)
./hello
echo -n abc | ./hello