2010-10-10 60 views
2

Python的fcnt模块提供了一个名为[flock] [1]的方法来证明文件锁定。它的描述如下:python的fcntl.flock函数是否提供文件访问的线程级锁定?

上文件 文件描述符fd执行锁定操作OP(文件对象提供 一个的fileno()方法被接受为 孔)。有关详细信息,请参阅Unix手册(2) 。 (在一些系统上,这个 功能被使用的fcntl()模拟)

仰望鸡群Linux手册页,它只是指跨越进程锁定,例如:

呼叫如果 不兼容的锁被另一个 进程占用,则可能会阻止()。要做出非阻塞 请求,请将LOCK_NB(ORing) 与上述任何操作一起包含。

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

[1]: - 事实上,他们不关心处理,无论是http://docs.python.org/library/fcntl.html#fcntl.flockfunction使用的fcntl())

回答

4

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.

请记住,对于Linux内核来说,进程和线程本质上是一回事,而且它们通常在内核级别的API下都是相同的。大多数情况下,如果一个系统调用记录进程间子进程/父进程行为,那么对于线程也是如此。

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

+4

你是否正在以一种循环的方式说,要正确使用锁定,你需要在每个上下文中获取不同的文件描述符? – 2012-09-19 21:56:50