问题:
Linux 中的flock等待锁的时候在做什么呢?是在循环检查锁是否已释放吗?
解答:
1. 将等待锁的进程置为阻塞状态
2. 当锁被释放时,再把等待锁的进程唤醒,等待锁的进程都在文件的结构中已链表的形式排队呢
3. 当进程意外死亡时,内核会自动释放其获得的锁资源
参考资料:
Linux 2.6 中的文件锁:http://www.ibm.com/developerworks/cn/linux/l-cn-filelock/index.html
摘录:
类型 | 字段 | 字段描述 |
struct file_lock* | fl_next | 与索引节点相关的锁列表中下一个元素 |
struct list_head | fl_link | 指向活跃列表或者被阻塞列表 |
struct list_head | fl_block | 指向锁等待列表 |
struct files_struct * | fl_owner | 锁拥有者的 files_struct |
unsigned int | fl_pid | 进程拥有者的 pid |
wait_queue_head_t | fl_wait | 被阻塞进程的等待队列 |
struct file * | fl_file | 指向文件对象 |
unsigned char | fl_flags | 锁标识 |
unsigned char | fl_type | 锁类型 |
loff_t | fl_start | 被锁区域的开始位移 |
loff_t | fl_end | 被锁区域的结束位移 |
struct fasync_struct * | fl_fasync | 用于租借暂停通知 |
unsigned long | fl_break_time | 租借的剩余时间 |
struct file_lock_operations * | fl_ops | 指向文件锁操作 |
struct lock_manager_operations * | fl_mops | 指向锁管理操作 |
union | fl_u | 文件系统特定信息 |
一个 file_lock 结构就是一把“锁”,结构中的 fl_file 就指向目标文件的 file 结构,而 fl_start 和 fl_end 则确定了该文件要加锁的一个区域。当进程发出系统调用来请求对某个文件加排他锁时,如果这个文件上已经加上了共享锁,那么排他锁请求不能被立即满足,这个进程必须先要被阻塞。这样,这个进程就被放进了等待队列,file_lock 结构中的 fl_wait 字段就指向这个等待队列。指向磁盘上相同文件的所有 file_lock 结构会被链接成一个单链表 file_lock_list,索引节点结构中的 i_flock 字段会指向该单链表结构的首元素,fl_next 用于指向该链表中的下一个元素;当前系统中所有被请求,但是未被允许的锁被串成一个链表:blocked_list。fl_link 字段指向这两个列表其中一个。对于被阻塞列表(blocked_list)上的每一个锁结构来说,fl_next 字段指向与该锁产生冲突的当前正在使用的锁。所有在等待同一个锁的那些锁会被链接起来,这就需要用到字段 fl_block,新来的等待者会被加入到等待列表的尾部。