linux 下文件锁
功能:使多个进程之间同步协调一致的访问文件的某个区域。
一、fcntl
1 | int fcntl(int fd, int cmd, struct flock* flockptr); |
如上,
- l_type是锁的类型:共享读锁(F_RDLCK),独占性写锁(F_WRLCK),解锁一个区域(F_UNLCK)
- 通常,对文件的操作都是从当前文件偏移处开始的,并使偏移量增加所读写的字节数。
- 如果l_whence为SEEK_SET,则将该文件的偏移量设置为距文件开始处 l_start 个字节
- 如果 l_whence 为 SEEK_CUR,则将该文件的偏移量设置为当前值加 l_start
- 如果 l_whence 为 SEEK_END,则将该文件的偏移量设置为文件长度加 l_start
- 若 l_len 为0,则表示锁的范围可以扩展到最大可能偏移量。这意味着不管向该文件追加写了多少数据,他们都可以处于锁的范围内,而且起始位置可以是文件中任何一个位置
- 如果对整个文件加锁,则可以设置 l_start 和 l_whence 指向文件的起始位置,并且指定长度 l_len 为0
fcntl 函数的cmd 参数
- F_GETLK:判断由 flockptr 所描述的锁是否会被另外一把锁所排斥(阻塞)。如果存在一把锁,它阻止创建由 flockptr 所描述的锁,则该现有锁的信息将重写 flockptr 指向的信息。如果不存在这个情况,则除了l_type设置为 F_UNLCK 之外,flockptr 所指向结构中的其他信息保持不变
- F_SETLK:设置由 flockptr 所描述的锁。如果获取不到则 fcntl 出错返回,此时 errno 被设置为 EACCES 或 EAGAIN。也可以清除由 flockptr 指定的锁
- F_SETLKW:这个cmd 是F_SETLK 的阻塞版本。如果加锁不能被授予则调用进程会休眠,如果请求创建的锁已经可用,或者休眠由信号中断,则该进程会被唤醒
注意:fcntl 对于写饥饿的问题没有明确规定(就是文件有了读锁,然后来了写锁,之后又来了读锁,那是否允许加这个读锁,写锁是否有可能一直阻塞)
后面补上例子代码