想象下面的代码作为一个线程运行:
void *thread_worker(void *q) {
for (;;) {
int fd = some_queue_get(q);
FILE *writer = fdopen(fd, "w");
if (!writer) { perror("fdopen"; close(fd); continue; }
// do something with writer
if (fclose(writer) == EOF) {
perror("fclose writer");
// should fd be closed here?
close(fd);
}
}
fclose(3)
可能由于各种原因而失败-是否有保证当底层文件描述符关闭或之后它仍然打开时?
- 如果在刷新失败时没有使用fclose关闭fd,则会泄漏fds而不需要额外关闭。
- 如果fd被fclose关闭,一个额外的关闭可能会关闭一个新被其他线程打开的文件描述符。
man fclose
也没有在我的系统上提供答案,但是man 3p fclose
显示了POSIX程序员手册的官方版本,它在这个问题上更加全面:
fclose()
函数将在与流所指向的流相关联的文件描述符上执行相当于close()
的操作。
答案是NO, C标准对此是模棱两可的(重点是我的):
7.21.5.1
fclose
函数简介
#include <stdio.h> int fclose(FILE *stream);
成功调用fclose
函数会导致stream
所指向的流被刷新,并关闭相关文件。流的任何未写入的缓冲数据都被交付给主机环境以写入文件;所有未读的缓冲数据将被丢弃。无论调用是否成功,流都与文件解除关联,并且setbuf
或setvbuf
函数设置的任何缓冲区都与流解除关联(如果是自动分配的,则释放)。
如果流已成功关闭,则fclose
函数返回0,如果检测到任何错误,则返回EOF
。