---------------------------------------------------------------------
在新的管理文件描述符的无锁模型中,锁机制是基于RCU的。文件描述表包含多个成员——fd sets(open_fds和close_on_exec,文件指针数组,文件描述符集和文件指针数组的大小)。为了使更新在一个无锁的读者看来是原子的,则文件描述符表的所有元素被放在一个单独的结构——struct fdtable中。
即,fdtable结构是进程的文件描述符表,其定义如下:
---------------------------------------------------------------------
include/linux/fdtable.h
struct fdtable {
unsigned int max_fds;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
struct rcu_head rcu;
struct fdtable *next;
};
---------------------------------------------------------------------
fd字段指向文件对象指针数组。该数组的长度存放在max_fds中。通常,fd字段指向files_struct的fd_array字段,该字段包含32个文件对象指针。如果进程打开的文件数目多于32个,内核就分配一个新的、更大的文件指针数组,并将其地址放在fd中,内核也同时更新max_fds字段的值。
对于在fd数组中有元素的每个文件来说,数组的索引就是文件描述符。Unix进程将文件描述符作为主文件标识符。两个文件描述符可以指向同一个打开的文件。
进程不能使用多于NR_OPEN个文件描述符。open_fds字段最初包含open_fds_init字段的地址,open_fds_init表示当前已打开文件描述符的位图。max_fds字段存放位图中的位数。
![]()
fd_set结构是文件描述符集,它将同一种情况下的多个文件描述符放在一起。在include/linux/types.h有中定义:
typedef __kernel_fd_setfd_set;
__kernel_fd_set结构在include/linux/posix_types.h中定义:
typedef struct {
unsigned long fds_bits [__FDSET_LONGS];
} __kernel_fd_set;
其中与__FDSET_LONGS有关的一些宏:
#define __NFDBITS (8 * sizeof(unsigned long))
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
#undef __FDSET_LONGS
#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)
embedded_fd_set结构是小的文件描述符集,它将同一情况下的文件描述符放在一起,只能存放unsigned long类型位数个文件描述符,不过,这对于许多进程已经足够了。
/*
* The embedded_fd_set is a small fd_set,
* suitable for most tasks (which open <= BITS_PER_LONG files)
*/
struct embedded_fd_set {
unsigned long fds_bits[1];
};
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-76274-2.html