linux - 文件写锁和子进程

标签 linux locking fcntl

如果一个进程给一个文件一个写锁,然后它生成一个子进程,锁会被子进程继承吗?如果是,那么有2个进程有写锁,我了解到只有1个进程可以有写锁,有些道理吗?这是一个测试Python代码

#!/usr/bin/python

import fcntl
import time
import os

fp = open('test.ini','w')
fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
pid = os.fork()

if pid > 0:
    time.sleep(10)
    exit(0)
if pid == 0:
    time.sleep(100)
    exit(0)

当父进程存在时,我尝试获取文件 test.ini 的锁,但是失败,所以我猜测子进程拥有锁

最佳答案

所以,正如您在 man page for flock(2) 中所指出的那样,锁与文件的关系如下:

Locks created by flock() are associated with an open file description (see open(2)). 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 file descriptors. Furthermore, the lock is released either by an explicit LOCK_UN operation on any of these duplicate file descriptors, or when all such file descriptors have been closed.

需要明确的是,它指出了释放锁时的两种情况:

  • 通过对任何这些重复文件描述符进行显式LOCK_UN操作
  • 当所有此类文件描述符都已关闭时

在问题中提供的代码中,父执行或子执行中都没有显式解锁,因此不会满足第一个条件。同样,由于第二个条件要求所有此类文件描述符都已关闭,因此提前终止父进程将无法满足这一要求;仅当子进程稍后终止时。

您可以通过添加显式解锁来满足这一点:

fcntl.flock(fp, fcntl.LOCK_UN)

在退出之前在父代码路径中,然后在子进程退出之前测试从单独的进程获取锁定。修改后的代码如下:

#!/usr/bin/python

import fcntl
import time
import os

fp = open('test.ini','w')
fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
pid = os.fork()

if pid > 0:
    time.sleep(10)
    fcntl.flock(fp, fcntl.LOCK_UN)
    exit(0)
if pid == 0:
    time.sleep(100)
    exit(0)

您还可以阅读/proc/locks或使用lslocks (相同的解析器)显示系统中当前持有的文件锁。前者的内容如下:

1: FLOCK  ADVISORY  WRITE 358 00:15:628 0 EOF
2: FLOCK  ADVISORY  WRITE 296 00:15:608 0 EOF
3: FLOCK  ADVISORY  WRITE 291 00:15:599 0 EOF
4: FLOCK  ADVISORY  WRITE 25874 b3:02:256617 0 EOF

以及后者的输出:

COMMAND           PID  TYPE SIZE MODE  M START END PATH
(unknown)       25874 FLOCK      WRITE 0     0   0 /...
cron              291 FLOCK      WRITE 0     0   0 /run...
(unknown)         296 FLOCK      WRITE 0     0   0 /run...
(unknown)         358 FLOCK      WRITE 0     0   0 /run...

当通过 PID 过滤此输出时,要使用的是父 PID,除非子进程中的模式已更改。

关于linux - 文件写锁和子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25599404/

相关文章:

node.js - 无法使用 n 更改 nodejs 版本

java - 如果在 HotSpot JVM 中启用了偏向锁定,对象的哈希码存储在哪里?

Mysql innodb 锁定 : IX should not be granted when X is held, 但确实

c - 使用c和fcntl在unix系统中锁定文件

linux - 如何使用 xargs 删除 iptables 规则?

python - 尝试在 python 代码中使用我的子网地址

linux - 输入rc : menu-complete-backward doesn't work on Mac OS X?

c++ - std::getline 函数错误 (fstreeam _Lock())

c - F_GETFL 和 F_SETFL 的使用

c - stat.h 文件访问文件描述符 open() 黑客利用的艺术