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相关推荐

  1. linux内核中的文件描述符(三)--fd的回收

    linux内核中的文件描述符(三)--fd的回收 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csd ...

  2. Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介

    原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...

  3. linux内核中的文件描述符(一)--基础知识简介

    linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.cs ...

  4. 简述linux内核中,Linux内核中的文件描述符(一)——基础知识简介

    2.文件描述符 下面进一步介绍进程对自己所访问的file对象的管理方法.linux中使用一个数组来管理进程打开的文件的file对象,数组中的每个元素都存放一个纸箱进程所打开的文件的file对象.既然用 ...

  5. linux 内核 遍历文件夹,Linux内核中通过文件描述符获取绝对路径

    背景 在Linux内核中,已知一个进程的pid和其打开文件的文件描述符fd,如何获取该文件的绝对路径?基本思路是先获取该文件在内核中的file结构体,再通过d_path()获取到整个文件的绝对路径. ...

  6. linux c中的文件描述符与打开文件之间的关系

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通 ...

  7. 理解Unix/Linux系统中的文件描述符

    简介 文件描述符是针对Unix/Linux的每个进程而言的,每个进程都维护了一个文件指针表,指针指向操作系统的文件.这里的文件是指的Unix/Linux系统所说的文件,Unix/Linux下一切皆文件 ...

  8. Linux中的文件描述符与打开文件之间的关系

    1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是 ...

  9. Linux中对文件描述符的操作(FD_ZERO、FD_SET、FD_CLR、FD_ISSET

    在Linux中,内核利用文件描述符(File Descriptor)即文件句柄,来访问文件.文件描述符是非负整数.打开现存文件或新建文件时,内核会返回一个文件描述符.读写文件也需要使用文件描述符来指定 ...

最新文章

  1. Android面试题详细整理系列(一)
  2. Middleware Monitor Cockpit SMWP
  3. [JS] Invalid Date
  4. Spring框架声明式事务管理
  5. Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02)
  6. spring+hibernate+mysql mvc 配置
  7. B站DR-CANup主电路系统建模_基尔霍夫定律的解题过程分析
  8. java打印某年日历_java打印指定年月份的日历
  9. libmodbus之嵌入式Linux使用及测试
  10. 虹科案例|基于SOLA光源的高通量Spike展示平台加速新冠病毒疫苗研制
  11. Oracle8.1.7 报错01033,win10系统下oracle数据库报错ORA-01033如何解决
  12. 同步时钟、异步时钟----概念解析
  13. unity学习笔记-换装系统
  14. 初入职场的你知道如何向领导邮件汇报工作吗
  15. Spring Boot框架入门到进阶教程(自学版)
  16. 岁月如水-指间流逝-难觅难留
  17. MTK平台获取本机的SIM卡中IMSI号
  18. 框架 也可以这样用 easy
  19. 计算机毕业设计安卓App毕设项目之springboot+合同管理APPNodejs毕业设计计算机项目源码
  20. 【记录】iOS网络缓存清理

热门文章

  1. PHP技术与应用基础
  2. Java-web css笔记
  3. MDI窗体的优化---下
  4. 【node.js】nvm安装最新教程
  5. TextView+Button
  6. @Inherited 的作用
  7. 23.MongoDB地理位置检索
  8. 数据库的几个性能指标
  9. Nature子刊 | 全球变化因子对土壤微生物多样性和功能的影响
  10. IMP ORA-20005: object statistics are locked(二)