linux内核中的文件描述符(四)--fd的分配--get_unused_fd
来源:互联网 发布:766冒险岛数据库没有了 编辑:程序博客网 时间:2024/05/17 07:13
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_NOFILE7/* max number of open files */
在signal结构中,rlim是struct rlimit类型的数组,
struct signal_struct {...struct rlimit rlim[RLIM_NLIMITS];...};struct rlimit定义如下
struct rlimit {unsigned longrlim_cur;//当前值unsigned longrlim_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的分配--locate_fd
- linux内核中的文件描述符(六)--fd的分配--expand_files
- linux内核中的文件描述符(三)--fd的回收
- Linux fd文件描述符的本来面目
- 查看linux中内核最大允许打开的fd(文件描述符)
- Linux中的文件描述符(fd)与打开文件之间的关系
- 浅谈 Linux 下的文件描述符 fd fp
- 文件描述符(fd)
- fd 文件描述符
- Linux内核中的文件描述符
- /dev/fd 文件描述符
- 文件描述符(fd)
- 文件描述符fd与文件指针FILE*的关系
- 文件描述符fd和文件指针FILE的区别
- 文件描述符fd和FILE的关系
- linux内核的文件描述
- 文件指针和文件描述符之间的相互转换 fd---->fp 和 fp---->fd
- 天天记录 - Java回调实现
- 游戏研发与风险控制
- 2013年10大网页设计趋势
- LoadRunner 11 安装及破解
- http协议学习
- linux内核中的文件描述符(四)--fd的分配--get_unused_fd
- Redis使用场景
- Windows Read Serial Support [php_serial.class.php ]
- 网站收藏
- 九度1031 xxx定律
- HTTP详解
- Ubuntu 10.04搭建JAVA开发环境
- java版快排。
- 1083. Networking(并查集求最小生成树)