C 当我试着从一根管子里读而不给它写信时会发生什么?

C 当我试着从一根管子里读而不给它写信时会发生什么?,c,pipe,C,Pipe,在这个操作中,我希望得到一个错误,因为我从零开始读取,但实际上程序似乎一直在尝试读取,直到有人向它写入。如果没有写操作,它将陷入试图读取的无限循环中,并且不会继续 这里的幕后到底发生了什么,函数是否一直在循环,或者它是在等待信号,还是在发生其他事情?它还在占用CPU资源吗 另外,当尝试在没有任何写入的情况下读取时,是否可以使程序返回错误代码/打印出一些内容?我真的不需要这么做,只是想知道这是否可能。这是正常的行为。如果没有可读取的内容,则读取过程将阻塞,直到有可用内容为止。阻塞时不会占用CPU时

在这个操作中,我希望得到一个错误,因为我从零开始读取,但实际上程序似乎一直在尝试读取,直到有人向它写入。如果没有写操作,它将陷入试图读取的无限循环中,并且不会继续

这里的幕后到底发生了什么,函数是否一直在循环,或者它是在等待信号,还是在发生其他事情?它还在占用CPU资源吗


另外,当尝试在没有任何写入的情况下读取时,是否可以使程序返回错误代码/打印出一些内容?我真的不需要这么做,只是想知道这是否可能。

这是正常的行为。如果没有可读取的内容,则读取过程将阻塞,直到有可用内容为止。阻塞时不会占用CPU时间;操作系统将使其休眠,直到另一个进程写入管道

请记住,管道的设计要有点透明;一个简单的过滤器类型程序不必关心输入是文件还是管道。如果每个希望能够从管道中读取数据的程序(想想
grep
)都必须包含特殊的处理,以等待编写器准备就绪,那么对于那些程序员来说,这将是非常乏味的。这种行为意味着从管道读取数据不需要执行任何特殊操作

如果您不想在没有可用数据的情况下阻止,可以在文件描述符上设置
O_NONBLOCK
状态标志,可以在
open(2)
it时,也可以使用
fcntl(fd,F_SETFL,…)
。在这种情况下,当没有可用数据时,
read(2)
将返回
-1
,并将
errno
设置为
EAGAIN
ewooldblock
。当然,这意味着每次读取文件描述符时,都必须编写代码来处理这种情况

您还可以使用
select(2)
poll(2)
等待数据可用,也可以选择超时


也可以对其进行安排,以便阻塞期间到达的信号将导致
read(2)
返回
-1
,并将
errno
设置为
EINTR
。这取决于系统调用重新启动语义,有点复杂。

管道的用途是有一个(或多个,但要小心)写入点和一个(或多个,但要小心)读取点。因此一个进程可以一直读取。如果管道(或队列)中没有任何内容,则不会读取任何内容。当其他进程写入管道时,您可以在读取端读取它。因此,读取空管道是完全有效的(您将读取0个条目)。中描述了该行为。通常,读取将是阻塞读取,并将等待数据出现,或管道的所有写入端关闭。阻塞时不会占用CPU时间。类似地,当管道充满时,写入程序会被阻塞(容量会有所不同;传统上,容量是5 KiB,但在现代类Unix系统上通常是64 KiB,尽管POSIX只需要4 KiB),或者直到管道上没有可用的读卡器为止。