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://test.idctop.com/article/477760.html

赞 (0)
什么是floorplan?floorplan和户型图有什么区别
上一篇 2026年7月10日 02:57
heatmapmin.js是什么?heatmap.min.js怎么用
下一篇 2026年7月10日 02:58

相关推荐

  • 服务器怎么防御攻击,攻击防御方法有哪些?

    服务器攻击防御的核心在于构建纵深防御体系,从网络层、系统层到应用层同步设防,配合专业服务商和应急流程,才能有效降低风险, 无论你是个人站长还是企业运维,理解攻击原理并落地具体措施,比盲目堆砌防御工具更重要,服务器防御攻击方案有哪些网络层防御:DDoS清洗与防火墙策略DDoS攻击是服务器最常见的威胁,通过流量清洗……

    2026年8月3日
    300
  • 新手从零学电脑入门难吗,零基础小白应该怎么学?

    掌握电脑操作并非高深的技术壁垒,而是建立在逻辑思维与肌肉记忆之上的系统化工程,对于新手从零学电脑入门而言,核心结论在于:电脑操作的本质是“输入指令”与“获取反馈”的过程,只要掌握了硬件交互、文件逻辑、软件管理及基础排错这四大支柱,即可快速从零跨越到熟练阶段, 学习过程不应盲目追求理论深度,而应优先建立对操作系统……

    2026年2月18日
    23200
  • 安卓socket通信机制是什么,安卓socket通信原理详解

    安卓Socket通信机制的核心在于建立可靠的TCP/UDP连接,通过输入输出流实现数据双向传输,其本质是网络进程间通信的标准化实现,需重点关注连接稳定性、数据序列化、异常处理三大技术环节,Socket通信基础架构协议选择TCP协议:适用于高可靠性场景,如金融交易数据传输,通过三次握手建立连接,提供数据重传机制……

    2026年3月22日
    9700
  • JazzVPS美国VPS好用吗,美国VPS推荐哪家稳定

    JazzVPS(原DiaHosting)凭借其在香港节点的低延迟优势以及美国线路的国内/国际双优化策略,是目前平衡访问速度与稳定性的高性价比选择,适合对海外服务器有特定网络环境需求的用户,JazzVPS品牌演变与核心定位解析JazzVPS的前身是业内知名的DiaHosting,这一品牌更迭并非简单的更名,而是服……

    2026年6月23日
    2000
  • api使用教程怎么操作?api使用教程详细步骤解析

    掌握API的正确调用方法,是实现系统集成与数据自动化的核心关键,高效的API使用流程必须遵循“明确需求、鉴权配置、调试测试、代码集成、监控维护”的标准化闭环,任何环节的疏漏都可能导致接口调用失败或数据传输错误,本教程将从实战角度出发,深入解析API调用的底层逻辑与操作细节,帮助开发者快速跨越技术门槛,实现业务逻……

    2026年3月27日
    9200
  • access数据库打包怎么操作,access数据库如何打包下载

    Access数据库打包的核心在于确保数据完整性、运行环境一致性以及部署的便捷性,最专业的解决方案是将应用程序与运行时环境剥离,构建独立的安装包,从而实现“一次打包,处处运行”,这不仅解决了版本兼容性问题,还极大降低了最终用户的使用门槛,是数据库开发交付的标准化流程,Access数据库打包的本质与价值许多开发者在……

    2026年4月8日
    8800
  • AJAX聊天室发送自定义消息接口能实现聊天室、弹幕等功能吗?

    完全可以实现,AJAX聊天室结合自定义消息接口,不仅能构建实时一对一或群聊系统,更是打造直播弹幕、实时协作白板等高频互动场景的核心技术底座,其优势在于无需刷新页面即可实现毫秒级数据同步,在2026年的Web开发语境下,传统的页面刷新模式早已退居二线,用户对于“即时性”的容忍度极低,任何超过200毫秒的延迟都可能……

    2026年6月12日
    3300
  • AngularJS教程怎么用?AngularJS入门到精通

    AngularJS 教程的核心在于掌握依赖注入与双向数据绑定机制,通过模块化开发实现前后端分离,从而构建高性能的单页面应用(SPA),在2026年的前端开发生态中,虽然Vue和React依然占据主流,但AngularJS作为早期SPA框架的代表,其设计思想依然深刻影响着现代前端架构,对于许多遗留系统的维护者或希……

    2026年6月13日
    2400
  • app数据压力测试难吗?Hadoop压力测试工具如何获取

    获取Hadoop压力测试工具最直接的方式是通过Apache官方仓库下载Hadoop自带的HDFS和MapReduce基准测试模块,或集成Apache Bench、JMeter等通用工具进行针对性压测,无需额外购买第三方商业软件,在App后端架构日益复杂的今天,数据吞吐量成为决定用户体验的关键瓶颈,当用户量激增时……

    2026年5月31日
    4600
  • linux怎么安装freetype?linux安装freetype报错怎么解决

    在Linux环境下安装FreeType最稳妥的方式是通过包管理器(如apt或yum)直接安装,若需最新特性或特定版本,则建议从源码编译安装,全程无需额外购买商业授权,完全免费开源,FreeType作为字体渲染的核心引擎,支撑着从Linux桌面到嵌入式设备的文字显示,很多开发者在配置服务器或开发环境时,常因依赖缺……

    2026年7月8日
    18400

发表回复

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

评论列表(1条)

  • 陈红
    陈红 2026年7月10日 16:35

    三点睡不着…这文章挺硬核。不过close了fd最好检查下返回值啊,不然资源泄漏了半夜找bug真的会谢…困死