2010-10-10 59 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