Linux close函数怎么用?linux关闭文件描述符方法

在 Linux 系统编程中,close() 是一个至关重要的系统调用,用于关闭一个打开的文件描述符(file descriptor)。

以下是关于 close() 函数的详细解析,包括原型、行为、返回值、常见陷阱以及最佳实践。

Linux系统编程:open/close函数详解
加载中
Linux系统编程:open/close函数详解

函数原型

#include <unistd.h>
int close(int fd);
  • 参数fd 是要关闭的文件描述符。
  • 返回值
    • 成功时返回 0
    • 失败时返回 -1,并设置 errno 以指示错误原因。

核心行为

当调用 close(fd) 时,内核执行以下操作:

  1. 引用计数检查

    • 每个打开的文件描述符在内核中都有一个引用计数。
    • 如果该描述符是通过 dup()fork() 共享的,关闭它只会减少引用计数,不会立即释放底层资源。
    • 只有当引用计数降为 0 时,内核才会真正释放该文件描述符占用的资源(如文件偏移量、打开文件状态标志等)。
  2. 释放资源

    • 如果引用计数为 0,内核会:
      • 释放文件描述符槽位(使其可被新打开的文件复用)。
      • 如果这是最后一个指向该打开文件表项的描述符,内核会执行

        Linux close函数怎么用?linux关闭文件描述符方法

        关闭操作(如刷新缓冲区、通知文件系统更新 inode 等)。

  3. 标准文件描述符

    • close(0) 关闭标准输入(stdin)。
    • close(1) 关闭标准输出(stdout)。
    • close(2) 关闭标准错误(stderr)。
    • 关闭这些描述符后,后续的 I/O 操作可能会失败或行为未定义,除非重新打开它们。

常见错误与 errno

错误码 含义 常见原因
EBADF 文件描述符无效 fd 不是有效的打开文件描述符(可能已关闭、从未打开或值非法)
EINTR 系统调用被信号中断 关闭操作被信号中断(罕见,但需处理)
EIO I/O 错误 底层文件系统或设备发生错误

最佳实践与注意事项

✅ 始终检查返回值

if (close(fd) == -1) {
    perror("close failed");
    // 根据程序逻辑决定是否退出或继续
}

✅ 关闭后不再使用

  • 关闭文件描述符后,不要再对该 fd 进行任何操作(如

    Linux close函数怎么用?linux关闭文件描述符方法

    read, write, lseek),否则会导致 EBADF 错误。

  • 建议将 fd 设为 -1 作为标记:
    close(fd);fd = -1; // 防止误用

✅ 处理 EINTR

虽然 close() 很少被信号中断,但在编写健壮代码时,应处理 EINTR

while (close(fd) == -1 && errno == EINTR) {
    // 被信号中断,重试
}
if (errno != 0) {
    perror("close failed");
}

✅ 与 dup()fork() 的关系

  • fd 是通过 dup(fd) 创建的,关闭其中一个副本不会影响另一个副本对底层文件的访问。
  • fork() 之后,子进程继承父进程的文件描述符,关闭父进程中的 fd 不会影响子进程中的副本,反之亦然。

✅ 资源泄漏

  • 忘记关闭文件描述符会导致资源泄漏(文件描述符耗尽、内存泄漏等)。
  • 在长时间运行的服务中,这可能导致程序崩溃或拒绝服务。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main() {
    int fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
       

Linux close函数怎么用?linux关闭文件描述符方法

perror("open failed"); return 1; } // 使用 fd 进行 read/write 操作... // 关闭文件描述符 if (close(fd) == -1) { perror("close failed"); return 1; } // 防止误用 fd = -1; printf("File closed successfully.n"); return 0; }

常见问题 FAQ

Q: close() 会删除文件吗?
A: 不会close() 只是关闭文件描述符,释放内核资源,要删除文件,应使用 unlink() 系统调用。

Q: 关闭标准输出(close(1))后,printf 还能用吗?
A: 不能printf 默认写入标准输出(fd 1),关闭后,printf 会失败或行为未定义,如果需要重定向输出,应先使用 dup2() 将新文件描述符复制到 fd 1。

Q: 如何确保文件数据已写入磁盘?
A: close() 会触发内核将缓冲区中的数据刷新到磁盘(通过 fsync() 机制),但不能保证物理磁盘已写入,如需强一致性,应在 close() 前调用 fsync(fd)


close() 是 Linux 文件 I/O 的基础操作,正确管理文件描述符的生命周期(打开 → 使用 → 关闭)是编写稳定、安全 C 程序的关键,务必检查返回值、处理错误,并避免资源泄漏。

首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/477760.html

(0)
什么是floorplan?floorplan和户型图有什么区别
上一篇 2026年7月10日 02:57
广州稳定DDOS安全吗,广州防DDOS攻击哪家最稳定
下一篇 2026年4月29日 05:32

相关推荐

  • linux下rar和zip怎么解压?linux解压rar和zip文件命令

    在Linux环境下,RAR格式因专利限制需安装专用工具,而ZIP作为开源标准无需额外软件即可原生支持,日常归档优先推荐ZIP,解压RAR文件则需配置第三方库,Linux下压缩格式的核心差异与选择逻辑在Linux服务器运维和日常文件管理中,压缩工具的选择往往决定了效率的上限,许多新手用户常陷入“RAR比ZIP压缩……

    2026年7月5日
    4600
  • linux怎么安装dialog?linux安装dialog详细教程

    在Linux系统中安装dialog包通常只需一条命令:Ubuntu/Debian系使用sudo apt install dialog,CentOS/RHEL系使用sudo yum install dialog,安装后即可通过命令行快速生成图形化交互界面,对于许多习惯了Windows图形界面的用户来说,Linux……

    2026年7月6日
    13600
  • Linux如何快速找到指定进程?查找Linux进程PID的方法

    在Linux系统中,最快找到指定进程的方法是直接使用ps aux | grep 进程名命令,若需实时监控资源占用,则推荐使用top或htop命令进行交互式查看,Linux系统以其稳定性和多任务处理能力著称,但这也意味着后台可能同时运行着成百上千个进程,当系统响应变慢或出现异常时,快速定位目标进程是运维人员的首要……

    2026年7月5日
    9900
  • Linux系统如何联网?Linux配置网络连接教程

    Linux系统联网的核心在于正确配置网络接口IP地址、子网掩码及网关,并通过DNS服务器实现域名解析,通常使用nmcli或netplan命令即可完成,在服务器运维或开发环境中,Linux系统的网络连接稳定性直接决定了业务连续性,许多初学者面对黑底白字的终端界面时,往往因为找不到图形化设置入口而感到困惑,现代Li……

    2026年7月7日
    11600
  • Linux下Skype 64位怎么安装?linux skype 64位下载

    检查版本,通常2.0以上版本兼容性最佳,测试音频设备:使用或

    2026年7月9日
    16700
  • linux find命令怎么用?linux find命令查找文件实例

    Linux find命令是系统管理员定位文件最高效的工具,通过组合名称、时间、权限和类型等条件,能在海量数据中精准锁定目标,无需依赖第三方软件,在Linux操作系统中,文件系统的层级结构往往错综复杂,尤其是当服务器运行多年、日志堆积如山时,手动查找特定文件无异于大海捞针,业内专家指出,掌握find命令不仅是基础……

    2026年7月9日
    6800
  • Linux select模型是什么?Linux select模型优缺点详解

    Linux select 模型通过单线程轮询机制管理文件描述符,虽在连接数超过1024时性能急剧下降,但在低并发、短连接或嵌入式设备场景中仍是简单可靠的I/O多路复用方案,select模型的核心原理与工作机制想象一下,你是一位餐厅经理,手里只有一根哨子,每当有客人(数据)到来,或者某张桌子(文件描述符)准备好了……

    2026年7月7日
    14400
  • linux lzma怎么解压?linux解压tar.xz文件命令

    在Linux系统中解压LZMA文件,最标准且高效的方法是使用xz命令配合-d参数,或者安装lzma工具包直接使用lzma -d命令,两者均支持递归解压和指定输出目录,是处理.lzma、.xz及.7z格式文件的首选方案,LZMA(Lempel-Ziv-Markov chain Algorithm)作为一种高压缩比……

    2026年7月4日
    13600
  • linux终端操作不会怎么办,linux常用命令大全

    Linux终端操作的核心在于掌握基础命令逻辑与权限管理,熟练运用管道符与重定向即可解决绝大多数日常运维与开发需求,很多初学者面对黑底白字的界面感到畏惧,其实Linux终端并非高不可攀的黑魔法,它更像是一把精密的手术刀,只要理解其背后的逻辑,你就能像指挥千军万马一样调度系统资源,本文将通过实战场景,拆解从入门到进……

    2026年7月6日
    7200
  • linux deb包怎么安装?linux deb包安装教程

    Linux下安装软件首选Debian包(.deb),它通过apt或dpkg工具实现依赖自动解析与版本管理,是Ubuntu、Deepin等主流发行版的标准软件分发格式,在Linux的生态版图中,Debian包不仅仅是一个文件后缀,它是连接开发者与用户的桥梁,对于习惯了Windows .exe一键安装或macOS……

    2026年7月8日
    6400

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注