同一进程内不同文件描述符调用flock(2)出现锁阻塞与解锁失效的原因咨询
嘿,我来帮你拆解这两个关于flock()的疑问,结合你给出的手册提示和测试代码来详细解释:
疑问I:为什么调用flock(fd2, LOCK_EX)会被阻塞?
首先得明确flock()锁的核心规则:虽然它的锁和文件描述符关联,但排他锁(LOCK_EX)是针对整个文件(inode)生效的,而且同一个进程的不同文件描述符会被flock()视为独立的锁请求主体。
你的测试代码里,fd1已经通过flock(fd1, LOCK_EX)持有了文件tfile.txt的排他锁。当你用另一个独立的文件描述符fd2发起LOCK_EX请求时,系统会检查该文件的锁状态:当前已有一个排他锁存在(哪怕是同一个进程持有的),而flock()的排他锁与任何锁(包括同一进程的其他fd持有的锁)都是互斥的。所以这个新的加锁请求会被阻塞,直到已有的排他锁被释放。
这完全符合手册里的提示:进程通过一个fd尝试锁定文件时,可能会被该进程已通过另一个fd设置的锁阻止。
疑问II:为什么调用flock(fd2, LOCK_UN)无法解除fd1上的文件锁?
手册里明确说了:flock()创建的锁与打开文件描述符相关联——简单来说,“谁加的锁,谁来解”,锁和加锁时用的fd是绑定的。
在你的代码中,排他锁是通过fd1加上的,而flock(fd2, LOCK_UN)只是尝试释放fd2上的锁,但fd2从来没有持有过任何锁,所以这个解锁操作实际上没有任何效果,完全不会影响fd1上持有的锁。只有用fd1调用LOCK_UN,或者关闭fd1(进程关闭fd时会自动释放该fd关联的锁),才能解除这个排他锁。
举个验证的例子,把代码改成这样就能正常运行:
int main(int argc, char **argv) { int fd1 = open("tfile.txt", O_RDWR); int fd2 = open("tfile.txt", O_RDWR); printf("fd1: %d, fd2: %d\n", fd1, fd2); flock(fd1, LOCK_EX); printf("Lock fd1....\n"); flock(fd1, LOCK_UN); // 用加锁的fd来解锁 printf("Unlock fd1....\n"); flock(fd2, LOCK_EX); printf("Lock fd2 success....\n"); // 此时不会阻塞 return 0; }
内容的提问来源于stack exchange,提问作者Licai Liu
相关产品推荐
相关产品推荐

