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

发布于 2024-09-27 03:57:27 字数 618 浏览 2 评论 0原文

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

对文件执行锁定操作op 描述符 fd(文件对象提供 fileno() 方法被接受为 出色地)。请参阅 Unix 手册集群(2) 了解详情。 (在某些系统上,这 函数使用 fcntl() 进行模拟。)

查找flock的linux手册页,它只涉及跨进程锁定,例如:

如果出现以下情况,则对集群()的调用可能会阻塞 不兼容的锁被另一个持有 过程。制作一个非阻塞的 请求,包括 LOCK_NB(通过 ORing) 与上述任何操作。

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

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

Python's fcnt module provides a method called [flock][1] to proved file locking. It's description reads:

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().)

Looking up the linux man page for flock, it only refers to cross process locking, for example:

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.

So my question is: will flock() also provide thread safe locking and lock multiple threads within the same process as well as threads from different processes?

[1]: http://docs.python.org/library/fcntl.html#fcntl.flockfunction is emulated using fcntl().)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浪荡不羁 2024-10-04 03:57:27

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 通常对它们进行相同的处理。在大多数情况下,如果系统调用记录进程间子/父行为,则同样适用于线程。

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

flock locks don't care about threads--in fact, they don't care about processes, either. If you take the same file descriptor in two processes (inherited through a fork), either process locking the file with that FD will acquire a lock for both processes. In other words, in the following code both flock calls will return success: the child process locks the file, and then the parent process acquires the same lock rather than blocking, because they're both the same 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)

On the same token, if you lock the same file twice, but with different file descriptors, the locks will block each other--regardless of whether you're in the same process or the same thread. See flock(2): If a process uses open(2) (or similar) to obtain more than one descriptor for the same file, these descriptors are treated independently by flock(). An attempt to lock the file using one of these file descriptors may be denied by a lock that the calling process has already placed via another descriptor.

It's useful to remember that to the Linux kernel, processes and threads are essentially the same thing, and they're generally treated the same by kernel-level APIs. For the most part, if a syscall documents interprocess child/parent behavior, the same will hold for threads.

Of course, you can (and probably should) test this behavior yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文