Linux close 函数详解
在 Linux 系统编程中,close 是一个非常基础且重要的系统调用,用于释放已打开的文件描述符。
函数原型
该函数定义在 <unistd.h> 头文件中:
#include <unistd.h> int close(int fd);
参数说明
- fd (File Descriptor): 这是一个非负整数,代表一个已打开的文件、套接字(socket)、管道(pipe)或其他 I/O 资源,该描述符通常是通过
open、socket、accept或pipe等系统调用返回的。
返回值
- 0: 表示操作成功。
- -1: 表示操作失败,并会设置全局变量
errno以指示具体的错误原因。
主要功能
当调用 close(fd) 时,内核会执行以下操作:
- 释放描述符: 将该文件描述符标记为“可用”,以便后续的系统调用(如
open)可以重新使用这个编号。 - 减少引用计数: 内核会减少指向该底层文件对象(file object)的引用计数,当引用计数降为 0 时,内核会执行真正的文件关闭操作(如释放内存、释放磁盘缓冲区等)。
- 触发资源回收: 对于网络套接字,
close会触发 TCP 的四次挥手流程;对于管道,关闭一端会向另一端发送 EOF(文件结束符)。
注意事项与最佳实践
- 防止资源泄漏: 这是最重要的一点,如果程序频繁打开文件或建立网络连接,但忘记调用
close,会导致文件描述符耗尽(达到进程或系统的限制),最终导致程序无法打开任何新文件或无法接收新连接。ulimit
- 数据完整性问题:
close函数并不保证所有数据都已物理写入磁盘,由于内核存在页缓存(Page Cache)机制,数据可能仍留在内存中,如果必须确保数据安全落地,应在调用close之前先调用fsync()或fdatasync()。 - 错误处理: 常见的错误码包括:
EBADF: 传入的fd不是一个有效的文件描述符。
- 避免重复关闭 (Double Close): 在多线程环境下,重复关闭同一个
fd是非常危险的,如果线程 A 关闭了fd,而线程 B 紧接着打开了一个新文件并恰好获得了相同的fd编号,此时线程 A 如果再次调用,就会错误地把线程 B 的文件给关掉。close(fd)
- 关闭顺序: 在复杂的 I/O 操作中,通常遵循“先处理数据,后关闭资源”的原则。
代码示例
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main() {
// 1. 打开一个文件
int fd = open("example.txt", O_RDONLY | O_CREAT, 0644);
if (fd == -1) {
perror("Open failed");
return 1;
}
printf("文件已打开,文件描述符为: %dn", fd);
// 2. 执行一些操作...
// 3. 关闭文件
if (close(fd) == -1) {
// 如果关闭失败,打印错误信息
fprintf(stderr, "Close failed: %sn", strerror(errno));
return 1;
}
printf("文件已成功关闭,n");
return 0;
}
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/491173.html



