APUE读书笔记

APUE学习笔记


第三章 文件I/O


1.文件描述符

1.1作用:

文件描述符是fd内核为了高效地管理已经被打开的文件所创建的索引,它是一个非负整数用来表示打开的文件。fd只是一个整数,在open时产生。进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp

1.2最大文件描述符个数:

系统最大打开文件描述符数:/proc/sys/fs/file-max

进程最大打开文件描述符数:$ulimit -n

查看当前系统使用的打开文件描述符数cat/proc/sys/fs/file-nr


1.3文件描述符和打开文件的关系:

每个进程在PCBProcessControlBlock)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针。对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用于描述打开的文件的数据块———file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的file对象。file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。

file对象中包含一个指针,指向dentry对象。dentry对象代表一个独立的文件路径,如果一个文件路径被打开多次,那么会建立多个file对象,但它们都指向同一个dentry对象。

dentry对象中又包含一个指向inode对象的指针。inode对象代表一个独立文件。因为存在硬链接与符号链接,因此不同的dentry对象可以指向相同的inode对象.inode对象包含了最终对文件进行操作所需的所有信息,如文件系统类型、文件的操作方法、文件的权限、访问日期等。打开文件后,进程得到的文件描述符实质上就是文件描述符表的下标,内核根据这个下标值去访问相应的文件对象,从而实现对文件的操作。

详细介绍:

1进程级文件描述符:

include/linux/sched.h中定义如下

structfiles_struct {

atomic_tcount; /*共享该表的进程数 */

rwlock_tfile_lock; /*保护以下的所有域,以免在tsk->alloc_lock中的嵌套*/

intmax_fds; /*当前文件对象的最大数*/

intmax_fdset; /*当前文件描述符的最大数*/

intnext_fd;*已分配的文件描述符加1*/

structfile ** fd; /*指向文件对象指针数组的指针*/

fd_set*close_on_exec; /*指向执行exec()时需要关闭的文件描述符*/

fd_set*open_fds; /*指向打开文件描述符的指针*/

fd_setclose_on_exec_init;/*执行exec()时需要关闭的文件描述符的初值集合*/

fd_set open_fds_init; /*文件描述符的初值集合*/

structfile * fd_array[32];/*文件对象指针的初始化数组*/

};

fd域指向文件对象的指针数组。该数组的长度存放在max_fds域中。通常,fd域指 files_struct结构的fd_array域,该域包括32个文件对象指针。对于在fd数组中有入口地址的每个文件来说,数组的索引就是文件描述符(filedescriptor)。open_fds域包含 open_fds_init域的地址,open_fds_init域表示当前已打开文件的文件描述符的位图。 max_fdset域存放位图中的位数。

2)系统级文件描述符表(打开的文件描述(openfile description))

include\linux\fs.h中定义如下:

structfile{

structlist_head f_list; /*所有打开的文件形成一个链表*/

structdentry *f_dentry; /*指向相关目录项的指针*/

structvfsmount *f_vfsmnt; /*指向VFS安装点的指针*/

structfile_operations *f_op; /*指向文件操作表的指针*/

mode_tf_mode; /*文件的打开模式*/

loff_tf_pos; /*文件的当前位置*/

unsignedshort f_flags; /*打开文件时所指定的标志*/

unsignedshort f_count; /*使用该结构的进程数*/

unsignedlong f_reada, f_ramax, f_raend, f_ralen, f_rawin;

/*预读标志、要预读的最多页面数、上次预读后的文件指针、预读的字节数以及

预读的页面数*/

intf_owner; /*通过信号进行异步I/O数据的传送*/

unsignedint f_uid, f_gid; /*用户的UIDGID*/

intf_error; /*网络写操作的错误码*/

unsignedlong f_version; /*版本号*/

void*private_data; /* tty驱动程序所需*/

};


每个文件对象总是包含在下列的一个双向循环链表之中:

·1.未使用”文件对象的链表。

·2.正在使用”文件对的象链表。



structfile_operations {

structmodule *owner;

loff_t(*llseek)(struct file *, loff_t, int);

ssize_t(*read)(struct file *, char __user *, size_t, loff_t *);

ssize_t(*aio_read)(struct kiocb *, char __user *, size_t, loff_t);

ssize_t(*write)(struct file *, const char __user *, size_t, loff_t *);

ssize_t(*aio_write)(struct kiocb *, const char __user *, size_t, loff_t);

int(*readdir) (struct file *, void *, filldir_t);

unsignedint (*poll) (struct file *, struct poll_table_struct *);

int(*ioctl) (struct inode *, struct file *, unsigned int, unsignedlong);

int(*mmap) (struct file *, struct vm_area_struct *);

int(*open) (struct inode *, struct file *);

int(*flush) (struct file *);

int(*release) (struct inode *, struct file *);

int(*fsync) (struct file *, struct dentry *, int datasync);

int(*aio_fsync) (struct kiocb *, int datasync);

int(*fasync) (int, struct file *, int);

int(*lock) (struct file *, int, struct file_lock *);

ssize_t(*readv)(struct file *, const struct iovec *, unsigned long, loff_t *);

ssize_t(*writev)(struct file *, const struct iovec *, unsigned long, loff_t *);

ssize_t(*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void __user *);

ssize_t(*sendpage)(struct file *, struct page *, int, size_t, loff_t *, int);

unsignedlong (*get_unmapped_area) (struct file *, unsigned long,

unsignedlong, unsigned long,unsignedlong);

};

structdentry {
  atomic_td_count;目录项对象使用计数器,可以有未使用态,使用态和负状态
  unsignedint d_flags;目录项标志
  structinode * d_inode;与文件名关联的索引节点
  structdentry * d_parent;父目录的目录项对象
  structlist_head d_hash;散列表表项的指针
  structlist_head d_lru;未使用链表的指针
  structlist_head d_child;父目录中目录项对象的链表的指针
  structlist_head d_subdirs;对目录而言,表示子目录目录项对象的链表
  structlist_head d_alias;相关索引节点(别名)的链表
  intd_mounted;对于安装点而言,表示被安装文件系统根项
  structqstr d_name;文件名
  unsignedlong d_time;
  structdentry_operations *d_op;目录项方法
  structsuper_block * d_sb;文件的超级块对象
  vunsignedlong d_vfs_flags;
  void* d_fsdata;与文件系统相关的数据
  unsignedchar d_iname [DNAME_INLINE_LEN];存放短文件名
};


参考

[1]APUE

[2]http://blog.csdn.net/cywosp/article/details/38965239

[3]http://blog.csdn.net/houliang120/article/details/39853959

[4]http://blog.sina.com.cn/s/blog_7943319e01018m3w.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值