Linux下面的兩種檔案鎖,Linux兩種檔案鎖
檔案鎖是一種檔案讀寫機制,在任何特定的時間只允許一個進程訪問一個檔案。利用這種機制能夠使讀寫單個檔案的過程變得更安全。
在這篇文章中,我們將探討Linux中不同類型的檔案鎖,並通過樣本程式來理解它們之間的不同之處。
我們將採取以下的例子來解釋為什麼需要使用檔案鎖。
1、 進程“A”開啟和讀取一個檔案,此檔案包含賬戶相關的一些資訊。
2、 進程“B”也開啟了這個檔案,並讀取了檔案中的資訊。
3、 現在,進程“A”更改了其副本中的一條餘額記錄,並將其寫入檔案。
4、 此時,進程“B”並不知道上次讀取的檔案已經被更改,它還儲存著原始的檔案副本。然後,進程“B”更改了“A”操作的那條相同的記錄,並將記錄寫入檔案。
5、 此時,檔案中將只儲存了進程“B”更改過的記錄。
為了避免這種事情發生,就要使用檔案鎖來確保操作的“序列化”。
以下是Linux系統中兩種常用的檔案鎖:
1、 協同鎖
協同鎖要求參與操作的進程之間協同合作。假設進程“A”獲得一個WRITE鎖,並開始向檔案中寫入內容;此時,進程“B”並沒有試圖擷取一個鎖,它仍然可以開啟檔案並向檔案中寫入內容。在此過程中,進程“B”就是一個非合作進程。如果進程“B”試圖擷取一個鎖,那麼整個過程就是一個合作的過程,從而可以保證操作的“序列化”。
只有當參與操作的進程是協同合作的時候,協同鎖才能發揮作用。協同鎖有時也被稱為“非強制”鎖。
2、 強制鎖
強制鎖不需要參與操作的進程之間保持協同合作。它利用核心來查檢每個開啟、讀取、寫入操作,從而保證在調用這些操作時不違反檔案上的鎖規則。關於強制鎖的更多資訊,可以在kernal.org上找到。
為了使能Linux中的強制鎖功能,你需要在檔案系統層級上開啟它,同時在單個檔案上開啟它。其步驟是:
1、 掛載檔案系統時使用“-o mand”參數。
2、 對於要開啟強制鎖功能的檔案lock_file,必須開啟set-group-ID位,關閉group-execute位。(選擇此方法的原因是,當你關閉group-execute時,設定set-group-ID就沒有實際的意義了)
Linux檔案鎖的樣本
為了理解檔案鎖是如何工作的,我們建立程式檔案file_lock.c:
include <stdio.h>#include <fcntl.h> intmain(intargc, char**argv) { if(argc > 1) { intfd = open(argv[1], O_WRONLY); if(fd == -1) { printf("Unable to open the file\n"); exit(1); } staticstruct flock lock; lock.l_type = F_WRLCK; lock.l_start = 0; lock.l_whence = SEEK_SET; lock.l_len = 0; lock.l_pid = getpid(); intret = fcntl(fd, F_SETLKW, &lock); printf("Return value of fcntl:%d\n",ret); if(ret==0) { while(1) { scanf("%c", NULL); } } }}
用gcc編譯此程式:
# cc -o file_lock file_lock.c |
使用mount命令帶“mand”參數來重新掛載根檔案系統,如下所示。這將在檔案系統層級使能強制鎖功能。注意:你必須切換到root使用者才能執行下面的命令。
在可執行檔(file_lock所在的)目錄中建立兩個名為“advisory.txt”和“mandatory.txt”的檔案。對於“mandatory.txt”使能Set-Group-ID,同時不使能Group-Execute-Bit,如下所示:
# touch advisory.txt# touch mandatory.txt# chmod g+s,g-x mandatory.txt |
測試協同鎖:執行樣本程式,以“advisory.txt”作為參數。
# ./file_lock advisory.txt |
此程式將等待使用者的輸入。從另一個終端或控制台,嘗試輸入以下命令列:
在上面的例子中,ls命令會將其輸出寫入到advisory.txt檔案中。即使我們獲得了一個寫入鎖,仍然會有一些進程(非合作)能夠往檔案裡寫入資料。這就是所謂的“協同”鎖。
測試強制鎖:再次執行樣本程式,以“mandatory.txt”作為參數。
# ./file_lock mandatory.txt |
從另一個終端或控制台,嘗試輸入以下命令列:
在上面的例子中,ls命令在將其輸出寫入到mandatory.txt檔案之前,會等待檔案鎖被刪除。雖然它仍然是一個非合作進程,但強制鎖起了作用。