`open`函数用于打开或创建文件,而`close`函数则用于关闭已打开的文件
本文将深入解析`close`函数的源码,探讨其内部机制及工作流程
一、`close`函数概述 `close`函数是Linux系统调用的一部分,用于关闭一个已经打开的文件
函数原型如下: int close(intfd); 其中,`fd`表示文件描述符,即`open`函数成功执行后返回的一个整数值
这个值是一个索引,指向内核中文件描述符表的一个条目,该条目包含了关于打开文件的所有信息
`close`函数的返回值表示操作的成功与否: - 成功时返回0
- 失败时返回-1,并设置全局变量`errno`以指示错误类型
二、`close`函数源码分析 为了深入理解`close`函数的机制,我们需要查看其源码
以下是`close`函数的核心实现部分,主要来自于Linux内核源码的简化版本: SYSCALL_DEFINE1(close, unsigned int,fd) { int retval =__close_fd(current->files, fd); ... return retval; } EXPORT_SYMBOL(sys_close); `SYSCALL_DEFINE1`是一个宏,用于定义系统调用
`close`函数接受一个无符号整数`fd`作为参数,并调用`__close_fd`函数来执行实际的关闭操作
接下来,我们深入`__close_fd`函数: int __close_fd(struct files_structfiles, unsigned fd) { structfile file; struct fdtablefdt; ... fdt = files_fdtable(files); ... file = fdt->fd【fd】; ... returnfilp_close(file,files); ... } 在`__close_fd`函数中,首先通过文件描述符表`fdt`找到对应的`file`结构
然后,调用`filp_close`函数来关闭文件
`filp_close`函数的实现如下: int filp_close(structfile filp, fl_owner_t id) { int retval = 0; ... fput(filp); return retval; } EXPORT_SYMBOL(filp_close); `filp_close`函数调用了`fput`函数,这是关闭文件操作的核心部分
接下来,我们进入`fput`函数的实现: void fput(struct filefile) { if(atomic_long_dec_and_test(&file->f_count)) { structtask_struct task = current; if(likely(!in_interrupt() &&!(task->flags & PF_KTHREAD))){ init_task_work(&file->f_u.fu_rcuhead,____fput); if(!task_work_add(task, &file->f_u.fu_rcuhead, true)) return; ... } ... } } `fput`函数首先通过`atomic_long_dec_and_test`减少`file->f_count`的值,并检查是否减到0
如果为0,表示这是最后一个指向该文件的