1. 程式人生 > >Linux中flock和fcntl區別

Linux中flock和fcntl區別

http://blog.csdn.net/icenic/article/details/8892461

從核心實現的角度來看,每當建立一把檔案鎖的時候,系統就會例項化一個struct file_lock物件,這個file_lock物件會記錄鎖的相關資訊:如鎖的型別(共享鎖,獨佔鎖)、擁有這把鎖的程序號、鎖的標識(租賃鎖,阻塞鎖,POSIX鎖,FLOCK鎖),等等。最後把這個file_lock物件插入到被鎖檔案的inode.i_flock連結串列中,就完成了對該檔案的加鎖功能。要是其它程序想要對同一個檔案加鎖,那麼它在將file_lock物件插入到inode.i_flock之前,會遍歷該連結串列,如果沒有發現衝突的鎖,就將其插入到連結串列尾,表示加鎖成功,否則失敗。

至於為什麼要將inode與file_lock以連結串列的形式關聯起來,主要是考慮到使用者有時可以對同一個檔案加多個檔案鎖。例如:我們可以對同一個檔案加多個共享鎖;或者我們可以同時對檔案加POSIX鎖和FLOCK鎖,這兩種鎖分別對應flock()和fcntl()兩種系統呼叫函式;再或者可以通過多次呼叫fcntl()對同一個檔案中的多個內容塊加上POSIX記錄鎖。

下面講下POSIX鎖和FLOCK鎖的一些區別:

1. POSIX鎖和FLOCK鎖分別是通過fcntl()和flock()系統呼叫完成的。雖然實現的原理上都差不多,都是生成一個file_lock物件並插入inode檔案鎖鏈表,但是POSIX鎖是支援針對某一段檔案內容進行加鎖的,而FLOCK鎖不支援。

2. POSIX鎖可以重複加鎖,即同一個程序,可以對同一個檔案多次加同樣一把鎖。例如:第一次我對A檔案的一個0~10的內容塊加了一把獨佔鎖,那麼第二次同一個程序中我一樣可以對這個A檔案的0~10的內容塊再加一把獨佔鎖,這個有點像是遞迴加鎖,但是我解鎖時只需要解一次。FLOCK鎖則不同,如果你第一次對A檔案加了一把獨佔鎖,那麼在同一個程序中你就不能對A檔案再加一把鎖了。這個區別其實只不過是在加鎖的時候,遍歷inode.i_flock連結串列時,發現存在PID相同的鎖時,系統對於POSIX鎖和FLOCK鎖的具體處理手段不一樣罷了。

3. 通過第2點,我們可以想象一下,POSIX鎖和FLOCK鎖在多執行緒環境下的不同。我們知道從Linux核心的視角來看,它是不區分所謂的程序和執行緒的,都不過是CPU排程佇列中的一個個task_struct例項而已,所以不會對執行緒的場景進行專門的處理,也正以為如此,平時我們用的NPTL執行緒庫也都是在使用者態環境中模擬出來的,Linux核心並不直接支援。回到剛剛的話題,因為核心它在加鎖的時候是看PID的,所以在核心看來多執行緒的加鎖只不過是同一個程序(因為每個執行緒的PID都是一樣的)在對同一個檔案加多把鎖。這樣,多執行緒環境下的加鎖行為就表現為:同一個程序中的多個執行緒可以對同一個檔案加多次POSIX獨佔或共享鎖,但是不可以對同一個檔案加多次FLOCK獨佔鎖(不過共享鎖是可以加多次的)。

4. 在一個專案中使用了GPFS共享檔案系統,我們在開發過程中發現,對於FLOCK鎖只支援本地,而POSIX鎖則可以支援跨主機加鎖。例如:我們有兩臺獨立的機器A和B,在A機器上有某個程序對檔案f加POSIX獨佔鎖,然後在B機器上當有某個程序想對f加POSIX獨佔鎖時,就會失敗。可是當我們使用FLOCK鎖時,就發現兩臺機器對同一個檔案加FLOCK鎖是互不影響的,即A和B機器都可以對f加獨佔鎖。針對這種情況,IBM工程師在郵件中給出的解釋如下:


關於檔案鎖的其他一些細節性的東西,可以參考這篇文章:http://www.ibm.com/developerworks/cn/linux/l-cn-filelock/
對於一些更加底層的細節問題,如:加鎖過程是隻在VFS層操作還是涉及到具體的物理檔案系統、GPFS上的POSIX檔案鎖如何做到跨機器有效,等等問題,可能就要參考原始碼了。

相關推薦

Linuxflockfcntl區別

http://blog.csdn.net/icenic/article/details/8892461 從核心實現的角度來看,每當建立一把檔案鎖的時候,系統就會例項化一個struct file_lock物件,這個file_lock物件會記錄鎖的相關資訊:如鎖的型別(共享鎖,

linux ll ls 區別

彩色 顯示文件 時間排序 linux 常用 所有 數字 名稱 sub ll 列出來的結果詳細,有時間,是否可讀寫等信息 ,象windows裏的 詳細信息ls 只列出文件名或目錄名 就象windows裏的 列表ll -t 是降序, ll -t | tac 是升序 ll不是

Linuxsusu -區別,別再傻傻分不清

寫在前面   如果你不清楚su和su -切換使用者的區別,你一定會遇到在使用su切換使用者執行命令出現報錯"command not found"感到驚訝。分明之前這個指令執行的好好的,為什麼現在就報錯了呢?關鍵原因就在於你不清楚su和su -命令使用的區別。 su與su -區別   su和

Linuxyumapt-get用法及區別

記錄 auto yum安裝軟件 mirror 內核 epo 綁定 提示 們的 Linux中yum和apt-get用法及區別 一般來說著名的linux系統基本上分兩大類: 1.RedHat系列:Redhat、Centos、Fedora等 2.Debian系列:De

linuxwhichwhereis、loacte、find的區別

幫助 可執行文件 執行 匹配 環境變量 命令 建立 環境變量path 當前 1,which在當前環境變量PATH中依此查找 一般用於查找命令/可執行文件所在路徑 2,whereis 返回與名稱匹配的二進制文件,源文件,幫助文件, 使用之前可以用updatadb命令來更新

linux find grep 的區別??

col linu 它的 -s glob 操作 功能 相關 round Linux 系統中 grep 命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。grep 全稱是 Global Regular Expression Print,表示

linuxllls的區別

linux下命令“ll”是“ls -l"的別名,"ll"和“ls -l”的功能是一樣的。 ls 命令可以說是linux下最常用的命令之一。 -a 列出目錄下的所有檔案,包括以 . 開頭的隱含檔案。 -b 把檔名中不可輸出的字元用反斜槓加字元編號(就象在C語言

linux,$*[email protected]有什麼區別

看了很多的文章,依然似懂非懂。現在,終於理解了它們兩者之間的區別。 $*會把當前指令碼的所有引數作為一個引數傳遞給子指令碼。(在英文中,*字元有“所有”的意思) [email protected]會把當前指令碼的所有引數分別作為一個引數傳遞給子指令碼。(在英文中,@字元有“獨立”的

linuxsusudo的區別

root使用者 su和sudo都用於執行具有root許可權的命令。root使用者基本上等同於Windows上的管理員使用者 - root使用者具有最大許可權,可以對系統執行任何操作。Linux上的普通使用者以較低的許可權執行 - 例如,他們無法安裝軟體或寫入系統目錄。 要執行需要這些

linux,$*[email protected]有什麼區別

看了很多的相關文章,似懂非懂。現在,終於真正理解了它們兩者之間的區別。 首先我們看如下一個bash命令: ./start.sh "a b" "c" "d" 請問,給start.sh指令碼傳遞了幾個引數? 大部分人都知道,總共傳遞了3個引數,其中,$1等於a b,$2等

Linuxmkdirtouch命令區別

原文地址:http://www.cnblogs.com/zfyouxi/p/5371317.html 一、目的         本文將介紹linux下新建檔案或資料夾、刪除檔案或資料夾命令。        touch能夠新建檔案,mkdir用來新建資料夾。rm用來刪除

linux .a.so的區別

本文轉載自http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 感謝原作者的精彩分享 函式庫分為靜態庫和動態庫兩種。 1. 靜態函式庫     這類庫的名字一般是libxxx.a;

linuxexportsource的作用區別

shell與export命令 使用者登入到Linux系統後,系統將啟動一個使用者shell。在這個shell中,可以使用shell命令或宣告變數,也可以建立並執行shell指令碼程式。執行shell指令碼程式時,系統將建立一個子shell。此時,系統中將有兩個shell

LinuxBufferCache的區別

2. Buffer:緩衝區,用於儲存速度不同步的裝置或優先順序不同的裝置之間傳輸資料;通過buffer可以減少程序間通訊需要等待的時間,當儲存速度快的裝置與儲存速度慢的裝置進行通訊時,儲存慢的資料先把資料存放到buffer,達到一定程度儲存快的裝置再讀取buffer的資料,在此期間儲存快的裝置CPU可以幹其他

Linuxrenamemv命令用法學習修改檔名區別總結

如何用命令修改檔名呢?在Linux下可以用rename命令,當然還可以使用mv命令,這裡分享下Linux rename命令的用法。 有一部分人說Linux下沒有rename命令,建議大家用mv命令。 對rename命令和mv命令在重新命名檔案方面做一個比較,大家根據個人

linux阻塞非阻塞的區別

所謂阻塞方式block,顧名思義,就是程序或是執行緒執行到這些函式時必須等待某個事件的發生,如果事件沒有發生,程序或執行緒就被阻塞,函式不能立即返回)。 所謂非阻塞方式non-block,就是程序或執行緒執行此函式時不必非要等待事件的發生,一旦執行肯定返回,以返回值的不同來

linuxmutexsemaphore的區別

很多程式設計的書裡在介紹mutex和semaphore的時候都會說,mutex是一種特殊的semaphore. 當semaphore的N=1時,就變成了binary semaphore,也就等同與mutex了。 但是實際上,在linux中,他們的實現什有區別的,導致最後應用

總結linux管線資料流重導向的詳解及區別

以下是自己的理解,有錯誤請指正下,謝謝 一:資料流重導向:我覺得就是把命令產生的結果儲存到檔案或者裝置, 或者把檔案或者裝置的內容傳給命令。      如:我要查出/dev 下所有的目錄檔案:      例1 把命令產生的結果儲存到檔案或者裝置:       ls -al

linuxmemcpystrcpy的區別

strcpy是拷貝字串,以\0為標誌結束(即一旦遇到資料值為0的記憶體地址拷貝過程即停止) strcpy的原型為: char *strcpy(char *dest, const char *src) 其在核心原始碼中(lib/string.h)的實現如下: char *st

Linuxchownchmod使用注意及區別

1,chown 修改檔案和資料夾的使用者和使用者組屬性 eg ,將目錄 /tmp/sco 這個目錄的所有者和組改為sakia和組net-->chown -R sakia:net /tmp/sco 2,chmod 修改檔案和資料夾讀寫執行屬性 eg,要修改/tmp/sc