标签:需要 问题 一个 假设 des table ati size 绑定
有时候需要保证同时只能有一个进程存在, 类似singleton的概念. 这时候简单方法就是对文件尝试加锁, 加锁成功就继续, 否则退出
函数定义如下:
int flock(int fd, int operation); // 第一个参数是fd
man-pages中对fd参数说明如下:
Locks created by flock() are associated with an open file table entry. This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these descriptors.
锁是和内核的file-entry绑定, 因此指向相同file-entry的fd是共享一个锁的. 比如父子进程, 或者通过dup复制的fd, 由于指向相同file-entry, 因此共享一个锁.
这里就有一个问题:
假设两个进程A和B. 分别open lockfile. 两个fd指向不同的file-entry. 此时A和B进程对fd加锁, 锁并没有关联到相同file-entry. 可以推断, 两个锁应该独立, 无法做到互斥. 但实际测试发现, 当A成功加锁后, B加锁会失败. 也就是说锁并不是独立的, 猜测锁其实是和inode关联的.
如果A成功加锁后, 将lockfile删除再新建lockfile. 此时lockfile的inode已经改变, 再启动B进程可以成功加锁. 因此猜测应该是对的, man-pages中的说明不太准确.
正确说法是: lock是和inode关联的, 一个inode同时有多个file-entry, 每个file-entry可以有多个fd. 这些fd都共享一个锁的逻辑.
struct inode {
struct hlist_node i_hash;
struct list_head i_list;
struct list_head i_sb_list;
struct list_head i_dentry;
unsigned long i_ino;
atomic_t i_count;
umode_t i_mode;
unsigned int i_nlink;
uid_t i_uid;
gid_t i_gid;
dev_t i_rdev;
loff_t i_size;
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
unsigned int i_blkbits;
unsigned long i_blksize;
unsigned long i_version;
unsigned long i_blocks;
unsigned short i_bytes;
unsigned char i_sock;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
struct semaphore i_sem;
struct rw_semaphore i_alloc_sem;
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
struct super_block *i_sb;
struct file_lock *i_flock; // 可以看到flock是和inode绑定的
标签:需要 问题 一个 假设 des table ati size 绑定
原文地址:https://www.cnblogs.com/shouzhuo/p/12276043.html