linux内核中的文件描述符(四)--fd的分配--get_unused_fd

发布者:dandan666最新更新时间:2016-03-02 来源: eefocus关键字:linux内核  文件描述符  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):

 

[plain] view plain copy
 
 print?
  1. int get_unused_fd(void)  
  2. {  
  3.     struct files_struct * files = current->files;//获得当前进程的打开文件列表files  
  4.     int fd, error;  
  5.     struct fdtable *fdt;  
  6.   
  7.     error = -EMFILE;  
  8.     spin_lock(&files->file_lock);  
  9.   
  10. repeat:  
  11.     fdt = files_fdtable(files);//获得文件描述符位图结构  
  12.     fd = find_next_zero_bit(fdt->open_fds->fds_bits,  
  13.                 fdt->max_fdset,  
  14.                 fdt->next_fd);  
  15. //find_next_zero_bit函数在文件描述符位图fds_bits中从next_fd位开始搜索下一个(包括next_fd)为0的位,也就是分配一个文教描述符  
  16.     /*  
  17.      * N.B. For clone tasks sharing a files structure, this test  
  18.      * will limit the total number of files that can be opened.  
  19.      */  
  20.     if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)//检查是否超过当前进程限定的最大可打开文件数  
  21.         goto out;  
  22.   
  23.     /* Do we need to expand the fd array or fd set?  */  
  24.     error = expand_files(files, fd);//根据需要扩展fd,稍后我们会详细介绍该函数。返回值<0,错误;返回值>0,扩展后再次进行fd的分配  
  25.     if (error < 0)  
  26.         goto out;  
  27.   
  28.     if (error) {  
  29.         /*  
  30.          * If we needed to expand the fs array we  
  31.          * might have blocked - try again.  
  32.          */  
  33.         error = -EMFILE;  
  34.         goto repeat;//之前进行了扩展操作,重新进行一次空闲fd的分配  
  35.     }  
  36.   
  37.     FD_SET(fd, fdt->open_fds);//在open_fds的位图上置位  
  38.     FD_CLR(fd, fdt->close_on_exec);  
  39.     fdt->next_fd = fd + 1;//next_fd加1  
  40. #if 1  
  41.     /* Sanity check */  
  42.     if (fdt->fd[fd] != NULL) {  
  43.         printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);  
  44.         fdt->fd[fd] = NULL;  
  45.     }  
  46. #endif  
  47.     error = fd;  
  48.   
  49. out:  
  50.     spin_unlock(&files->file_lock);  
  51.     return error;  
  52. }  

 

current->signal->rlim[RLIMIT_NOFILE].rlim_cur是一个进程可以打开的最大文件数量。我们首先来看RLIMIT_NOFILE,该值定义如下:

 

[plain] view plain copy
 
 print?
  1. # define RLIMIT_NOFILE      7   /* max number of open files */  

 

在signal结构中,rlim是struct rlimit类型的数组,

 

[plain] view plain copy
 
 print?
  1. struct signal_struct {  
  2.     ...  
  3.     struct rlimit rlim[RLIM_NLIMITS];  
  4.     ...   
  5. };  
struct rlimit定义如下
[plain] view plain copy
 
 print?
  1. struct rlimit {  
  2.     unsigned long   rlim_cur;//当前值  
  3.     unsigned long   rlim_max;//最大值  
  4. };  

这些值时是在哪设定的呢?我们应该知道,linux内核通过fork创建进程,第一个进程是静态定义的。因此,如果进程创建后没有修改这些值,那么这些和第一个进程中的值应该是一样的。下面是第一个进程的task_struct结构,仅列出部分数据。

 

[plain] view plain copy
 
 print?
  1. linux/arch/arm/kernel/init_task.c  
  2.   
  3. struct task_struct init_task = INIT_TASK(init_task);  
  4.   
  5. #define INIT_TASK(tsk)  \  
  6. {                                   \  
  7.     ...  
  8.     .signal     = &init_signals,                \  
  9.     ...           
  10. }  
init_signals的定义如下:

 

 

 

[plain] view plain copy
 
 print?
  1. #define INIT_SIGNALS(sig) { \  
  2.     .count      = ATOMIC_INIT(1),       \  
  3.     .wait_chldexit  = __WAIT_QUEUE_HEAD_INITIALIZER(sig.wait_chldexit),\  
  4.     .shared_pending = {                 \  
  5.         .list = LIST_HEAD_INIT(sig.shared_pending.list),    \  
  6.         .signal =  {{0}}}, \  
  7.     .posix_timers    = LIST_HEAD_INIT(sig.posix_timers),        \  
  8.     .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers),      \  
  9.     .rlim       = INIT_RLIMITS,                 \  
  10. }  
  11.   
  12. include\asm-generic\resource.h  
  13. #define INIT_RLIMITS                            \  
  14. {                                   \  
  15.     [RLIMIT_CPU]        = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  16.     [RLIMIT_FSIZE]      = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  17.     [RLIMIT_DATA]       = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  18.     [RLIMIT_STACK]      = {       _STK_LIM,   _STK_LIM_MAX },   \  
  19.     [RLIMIT_CORE]       = {              0,  RLIM_INFINITY },   \  
  20.     [RLIMIT_RSS]        = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  21.     [RLIMIT_NPROC]      = {              0,              0 },   \  
  22.     [RLIMIT_NOFILE]     = {       INR_OPEN,       INR_OPEN },   \  
  23.     [RLIMIT_MEMLOCK]    = {    MLOCK_LIMIT,    MLOCK_LIMIT },   \  
  24.     [RLIMIT_AS]     = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  25.     [RLIMIT_LOCKS]      = {  RLIM_INFINITY,  RLIM_INFINITY },   \  
  26.     [RLIMIT_SIGPENDING] = {         0,         0 }, \  
  27.     [RLIMIT_MSGQUEUE]   = {   MQ_BYTES_MAX,   MQ_BYTES_MAX },   \  
  28.     [RLIMIT_NICE]       = { 0, 0 },             \  
  29.     [RLIMIT_RTPRIO]     = { 0, 0 },             \  
  30. }  
  31.   
  32. #define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */  
  33. #define INR_OPEN 1024       /* Initial setting for nfile rlimits */  
从上面的代码我们可以看到rlim_cur = 1024,也就是说进程最多可以打开1024个文件。
关键字:linux内核  文件描述符  get_unused_fd 引用地址:linux内核中的文件描述符(四)--fd的分配--get_unused_fd

上一篇:linux内核中的文件描述符(五)--fd的分配--locate_fd
下一篇:linux内核中的文件描述符(三)--fd的回收

推荐阅读最新更新时间:2024-03-16 14:45

linux内核中的likely和unlikely
Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net/ce123) GCC version:arm-linux-gcc-3.4.1 看内核时经常遇到if(likely( )){}或是if(unlikely( ))这样的语句,不甚了解,例如(选自kernel/fork.c中copy_process): view plain copy print ? SET_LINKS(p); if (unlikely(p- ptrace & PT_PTRACED)) __ptrace_link(p,
[单片机]
s3c2410 RTC驱动框架linux内核源码分析
/********************************************************************************************************* * @Description:s3c2410的rtc驱动的实现,rtc(real time clock)实时时钟的驱动是个很好的 * 理解如果编写驱动的硬件,它包括了最基本的硬中断,软中断的底层机制; * s3c2410的RTC驱动的实现个人认为更是对linux设备驱动一个很好的例子,他是通过二层结构来 * 实现的一个驱动,上层是一个arm common的公共层,对上提供标准的通用的RTC操作接口,下层由 * 我
[单片机]
s3c2410 RTC驱动框架<font color='red'>linux内核</font>源码分析
谷歌第三款移动操作系统Fuchsia放弃Linux内核
腾讯科技讯 据外媒报道,谷歌(微博)从来都没有想过凭借一款产品征战市场,它显然不满足于Android和Chrome OS,它正在努力开发一款名为“Fuchsia”的开源、实时OS。 这款操作系统曾在去年8月让世人惊鸿一瞥,但是当时它还只是一个命令行,现在这个神秘项目的用户界面(UI)终于浮出水面。 与Android和Chrome OS不同,Fuchsia并不是建立在Linux之上,它采用的是谷歌自主研发的微内核“Magenta”。在Fuchsia项目上,谷歌不仅放弃了Linux内核,而且还丢掉了GPL。这款操作系统是按照BSD 3条款、MIT和Apache 2.0进行授权的。放弃Linux内核或许有些令人意外,但是Andr
[手机便携]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved