文件描述符关闭时阻塞函数的行为?管道read阻塞场景问询
关于管道阻塞时关闭文件描述符的行为解析
先直接给你明确两个问题的答案,再展开细节:
1. 当阻塞于某fd的系统调用遇到该fd被关闭时的行为
不管是read(2)、write(2)还是其他阻塞在这个fd上的系统调用,一旦这个fd被关闭(不管是当前线程还是其他线程执行的关闭操作),阻塞的调用会立即被唤醒,并返回-1,同时将errno设置为EBADF(表示“无效的文件描述符”)。
这里要注意一个多线程场景的坑:关闭fd后,这个fd编号可能很快被内核重新分配给新的打开操作(比如另一个线程调用open(2)),如果原阻塞调用醒来后误以为还是原来的fd,就会出现错误操作——这属于编程逻辑漏洞,规范的做法是关闭fd后要确保代码不再引用这个编号。
2. 管道空时阻塞的read(2)被关闭fd后的结果
这是上面通用场景的具体实例:当read(2)因管道缓冲区为空而阻塞时,如果当前正在使用的读fd被关闭,read(2)会立刻停止阻塞,返回-1,errno同样被设为EBADF。
这里要和「管道写端被全部关闭」的情况严格区分:如果是管道的所有写端都被关闭,此时阻塞的read(2)会返回0(表示读到了EOF),这是管道正常结束的逻辑,和关闭自身读fd的异常返回完全是两回事。
补充个小建议:如果想更可控地处理这类场景,可以用
fcntl(2)给fd设置O_NONBLOCK标志,结合select(2)/poll(2)来监听I/O事件,避免无差别阻塞带来的意外中断。
内容的提问来源于stack exchange,提问作者szxwpmj
相关产品推荐
相关产品推荐

