python - python 的 fcntl.flock 函数是否提供文件访问的线程级锁定?

标签 python linux multithreading locking flock

Python 的 fcnt 模块提供了一种名为 [flock][1] 的方法来证明文件锁定。它的描述如下:

Perform the lock operation op on file descriptor fd (file objects providing a fileno() method are accepted as well). See the Unix manual flock(2) for details. (On some systems, this function is emulated using fcntl().)

查找flock的linux手册页,只提到跨进程锁定,例如:

A call to flock() may block if an incompatible lock is held by another process. To make a non-blocking request, include LOCK_NB (by ORing) with any of the above operations.

所以我的问题是:flock() 还会提供线程安全锁定并锁定同一进程内的多个线程以及来自不同进程的线程吗?

[1]:http://docs.python.org/library/fcntl.html#fcntl.flockfunction使用 fcntl() 进行模拟。)

最佳答案

flock 锁不关心线程——事实上,它们也不关心进程。如果在两个进程中使用相同的文件描述符(通过 fork 继承),则使用该 FD 锁定文件的任一进程都将获取两个进程的锁。换句话说,在下面的代码中,两个 flock 调用都会返回成功:子进程锁定文件,然后父进程获取相同的锁而不是阻塞,因为他们都是同一个FD。

import fcntl, time, os

f = open("testfile", "w+")
print "Locking..."
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
print "locked"
fcntl.flock(f.fileno(), fcntl.LOCK_UN)

if os.fork() == 0:
    # We're in the child process, and we have an inherited copy of the fd.
    # Lock the file.
    print "Child process locking..."
    fcntl.flock(f.fileno(), fcntl.LOCK_EX)
    print "Child process locked..."
    time.sleep(1000)
else:
    # We're in the parent.  Give the child process a moment to lock the file.
    time.sleep(0.5)

    print "Parent process locking..."
    fcntl.flock(f.fileno(), fcntl.LOCK_EX)
    print "Parent process locked"
    time.sleep(1000)

同样,如果您两次锁定同一个文件,但使用不同的文件描述符,则锁将相互阻塞 - 无论您是否位于同一进程或同一线程中。参见flock(2):如果一个进程使用open(2)(或类似的)来获取同一文件的多个描述符,这些描述符将由flock()独立处理。使用这些文件描述符之一锁定文件的尝试可能会被调用进程已经通过另一个描述符放置的锁拒绝。

记住,对于 Linux 内核来说,进程和线程本质上是同一件事,并且内核级 API 通常对它们进行相同的处理。在大多数情况下,如果系统调用记录进程间子/父行为,则同样适用于线程。

当然,您可以(并且可能应该)自己测试此行为。

关于python - python 的 fcntl.flock 函数是否提供文件访问的线程级锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3899435/

相关文章:

multithreading - 为什么 Windows NT 线程具有独立的用户模式/内核模式堆栈?

python - 将计数字段添加到 django rest 框架序列化程序

python - 在 python 中扩展列表直到满足条件

linux - 硬链接(hard link) - 存储

c - 数字生成器未在 C 中打印出预期的第一个数字

python - 检查当前在 python 中执行的线程

python - 为什么在 Python 中叫运算符重载而不是重写?

python - 从 UDP 套接字读取所有数据

linux - bash脚本: using "script" command to write console output to a file in real time

linux - yum和rpm显示安装的包数不一样