linux内核中的文件描述符(四)--fd的分配--get_unused_fd
linux内核中的文件描述符(四)--fd的分配--get_unused_fd
Kernel version:2.6.14
CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
在linux内核中主要有两个函数涉及到文件描述符的分配:get_unused_fd和locate_fd。本文主要讲解get_unused_fd,将会在下一篇文章中介绍locate_fd。首先给出get_unused_fd的定义(fs/open.c):
int get_unused_fd(void)
{struct files_struct * files = current->files;//获得当前进程的打开文件列表filesint fd, error;struct fdtable *fdt;error = -EMFILE;spin_lock(&files->file_lock);repeat:fdt = files_fdtable(files);//获得文件描述符位图结构fd = find_next_zero_bit(fdt->open_fds->fds_bits,fdt->max_fdset,fdt->next_fd);
//find_next_zero_bit函数在文件描述符位图fds_bits中从next_fd位开始搜索下一个(包括next_fd)为0的位,也就是分配一个文教描述符/** N.B. For clone tasks sharing a files structure, this test* will limit the total number of files that can be opened.*/if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//检查是否超过当前进程限定的最大可打开文件数goto out;/* Do we need to expand the fd array or fd set? */error = expand_files(files, fd);//根据需要扩展fd,稍后我们会详细介绍该函数。返回值<0,错误;返回值>0,扩展后再次进行fd的分配if (error < 0)goto out;if (error) {/** If we needed to expand the fs array we* might have blocked - try again.*/error = -EMFILE;goto repeat;//之前进行了扩展操作,重新进行一次空闲fd的分配}FD_SET(fd, fdt->open_fds);//在open_fds的位图上置位FD_CLR(fd, fdt->close_on_exec);fdt->next_fd = fd + 1;//next_fd加1
#if 1/* Sanity check */if (fdt->fd[fd] != NULL) {printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);fdt->fd[fd] = NULL;}
#endiferror = fd;out:spin_unlock(&files->file_lock);return error;
}
current->signal->rlim[RLIMIT_NOFILE].rlim_cur是一个进程可以打开的最大文件数量。我们首先来看RLIMIT_NOFILE,该值定义如下:
# define RLIMIT_NOFILE 7 /* max number of open files */
在signal结构中,rlim是struct rlimit类型的数组,
struct signal_struct {...struct rlimit rlim[RLIM_NLIMITS];...
};
struct rlimit定义如下
struct rlimit {unsigned long rlim_cur;//当前值unsigned long rlim_max;//最大值
};
这些值时是在哪设定的呢?我们应该知道,linux内核通过fork创建进程,第一个进程是静态定义的。因此,如果进程创建后没有修改这些值,那么这些和第一个进程中的值应该是一样的。下面是第一个进程的task_struct结构,仅列出部分数据。
linux/arch/arm/kernel/init_task.cstruct task_struct init_task = INIT_TASK(init_task);#define INIT_TASK(tsk) \
{ \....signal = &init_signals, \...
}
init_signals的定义如下:
#define INIT_SIGNALS(sig) { \.count = ATOMIC_INIT(1), \.wait_chldexit = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\.shared_pending = { \.list = LIST_HEAD_INIT(sig.shared_pending.list), \.signal = {{0}}}, \.posix_timers = LIST_HEAD_INIT(sig.posix_timers), \.cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \.rlim = INIT_RLIMITS, \
}include\asm-generic\resource.h
#define INIT_RLIMITS \
{ \[RLIMIT_CPU] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_FSIZE] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_DATA] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_STACK] = { _STK_LIM, _STK_LIM_MAX }, \[RLIMIT_CORE] = { 0, RLIM_INFINITY }, \[RLIMIT_RSS] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_NPROC] = { 0, 0 }, \[RLIMIT_NOFILE] = { INR_OPEN, INR_OPEN }, \[RLIMIT_MEMLOCK] = { MLOCK_LIMIT, MLOCK_LIMIT }, \[RLIMIT_AS] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_LOCKS] = { RLIM_INFINITY, RLIM_INFINITY }, \[RLIMIT_SIGPENDING] = { 0, 0 }, \[RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \[RLIMIT_NICE] = { 0, 0 }, \[RLIMIT_RTPRIO] = { 0, 0 }, \
}#define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */
#define INR_OPEN 1024 /* Initial setting for nfile rlimits */
从上面的代码我们可以看到rlim_cur = 1024,也就是说进程最多可以打开1024个文件。
linux内核中的文件描述符(四)--fd的分配--get_unused_fd相关推荐
- linux内核中的文件描述符(三)--fd的回收
linux内核中的文件描述符(三)--fd的回收 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csd ...
- Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介
原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...
- linux内核中的文件描述符(一)--基础知识简介
linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.cs ...
- 简述linux内核中,Linux内核中的文件描述符(一)——基础知识简介
2.文件描述符 下面进一步介绍进程对自己所访问的file对象的管理方法.linux中使用一个数组来管理进程打开的文件的file对象,数组中的每个元素都存放一个纸箱进程所打开的文件的file对象.既然用 ...
- linux 内核 遍历文件夹,Linux内核中通过文件描述符获取绝对路径
背景 在Linux内核中,已知一个进程的pid和其打开文件的文件描述符fd,如何获取该文件的绝对路径?基本思路是先获取该文件在内核中的file结构体,再通过d_path()获取到整个文件的绝对路径. ...
- linux c中的文件描述符与打开文件之间的关系
转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通 ...
- 理解Unix/Linux系统中的文件描述符
简介 文件描述符是针对Unix/Linux的每个进程而言的,每个进程都维护了一个文件指针表,指针指向操作系统的文件.这里的文件是指的Unix/Linux系统所说的文件,Unix/Linux下一切皆文件 ...
- Linux中的文件描述符与打开文件之间的关系
1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是 ...
- Linux中对文件描述符的操作(FD_ZERO、FD_SET、FD_CLR、FD_ISSET
在Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描述符.读写文件也需要使用文件描述符来指定 ...
最新文章
- Android面试题详细整理系列(一)
- Middleware Monitor Cockpit SMWP
- [JS] Invalid Date
- Spring框架声明式事务管理
- Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02)
- spring+hibernate+mysql mvc 配置
- B站DR-CANup主电路系统建模_基尔霍夫定律的解题过程分析
- java打印某年日历_java打印指定年月份的日历
- libmodbus之嵌入式Linux使用及测试
- 虹科案例|基于SOLA光源的高通量Spike展示平台加速新冠病毒疫苗研制
- Oracle8.1.7 报错01033,win10系统下oracle数据库报错ORA-01033如何解决
- 同步时钟、异步时钟----概念解析
- unity学习笔记-换装系统
- 初入职场的你知道如何向领导邮件汇报工作吗
- Spring Boot框架入门到进阶教程(自学版)
- 岁月如水-指间流逝-难觅难留
- MTK平台获取本机的SIM卡中IMSI号
- 框架 也可以这样用 easy
- 计算机毕业设计安卓App毕设项目之springboot+合同管理APPNodejs毕业设计计算机项目源码
- 【记录】iOS网络缓存清理