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

Python的fcnt模块提供了一个名为[flock] [1]的方法来certificate文件locking。 它的描述如下:

对文件描述符fd执行锁操作op(也接受提供fileno()方法的文件对象)。 有关详细信息,请参阅Unix手册(2)。 (在某些系统上,这个函数是用fcntl()模拟的。)

查看flock的linux手册页,只涉及到跨进程locking,例如:

对flock()的调用可能会阻止另一个进程持有不兼容的锁。 要做出一个非阻塞的请求,包括LOCK_NB(ORing)与上述任何操作。

所以我的问题是:将flock()还提供线程安全locking和locking同一进程内的多个线程以及来自不同进程的线程?

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

Solutions Collecting From Web of "python的fcntl.flock函数是否提供文件访问的线程级locking?"

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

记住对于Linux内核来说,进程和线程本质上是一回事,而且内核级别的API通常也是这样处理的。 大多数情况下,如果一个系统调用文档进程之间的子/父行为,线程也一样。

当然,你可以(也可能应该)自己测试这个行为。