Linux中的兩種文件鎖—協同鎖與強制鎖

fmms 12年前發布 | 11K 次閱讀 Linux

        英文原文:2 Types of Linux File Locking (Advisory, Mandatory Lock Examples)

        文件鎖是一種文件讀寫機制,在任何特定的時間只允許一個進程訪問一個文件。利用這種機制能夠使讀寫單個文件的過程變得更安全。

        在這篇文章中,我們將探討 Linux 中不同類型的文件鎖,并通過示例程序來理解它們之間的不同之處。

        我們將采取以下的例子來解釋為什么需要使用文件鎖。

        1、  進程“A”打開和讀取一個文件,此文件包含賬戶相關的一些信息。

        2、  進程“B”也打開了這個文件,并讀取了文件中的信息。

        3、  現在,進程“A”更改了其副本中的一條余額記錄,并將其寫入文件。

        4、  此時,進程“B”并不知道上次讀取的文件已經被更改,它還保存著原始的文件副本。然后,進程“B”更改了“A”操作的那條相同的記錄,并將記錄寫入文件。

        5、  此時,文件中將只保存了進程“B”更改過的記錄。

        為了避免這種事情發生,就要使用文件鎖來確保操作的“序列化”。

        以下是 Linux 系統中兩種常用的文件鎖:

        1、  協同鎖

        2、  強制鎖

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 

    


#include 

     


      int main (

      int argc, 

      char **argv) {


      if (argc > 

      1) {


      int fd = open (argv[

      1], O_WRONLY);


      if(fd == -

      1) {
      printf (

      "

      Unable to open the file\n

      ");
      exit (

      1);
    }


      static 

      struct flock 

      lock;



      lock.l_type = F_WRLCK;


      lock.l_start = ;


      lock.l_whence = SEEK_SET;


      lock.l_len = ;


      lock.l_pid = getpid ();



      int ret = fcntl (fd, F_SETLKW, &

      lock);
    printf (

      "

      Return value of fcntl:%d\n

      ",ret);


      if(ret==) {


      while (

      1) {
        scanf (

      "

      %c

      ", NULL);
      }
    }
  }
}

     

    

        用 gcc 編譯此程序:

# cc -o file_lock file_lock.c

        使用 mount 命令帶“mand”參數來重新掛載根文件系統,如下所示。這將在文件系統級別使能強制鎖功能。注意:你必須切換到 root 用戶才能執行下面的命令。

# mount -oremount,mand /

        在可執行的(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

        在上面的例子中,ls 命令會將其輸出寫入到 advisory.txt 文件中。即使我們獲得了一個寫入鎖,仍然會有一些進程(非合作)能夠往文件里寫入數據。這就是所謂的“協同”鎖。

        測試強制鎖:再次執行示例程序,以“mandatory.txt”作為參數。

# ./file_lock mandatory.txt

        從另一個終端或控制臺,嘗試輸入以下命令行:

# ls >>mandatory.txt

        在上面的例子中,ls 命令在將其輸出寫入到 mandatory.txt 文件之前,會等待文件鎖被刪除。雖然它仍然是一個非合作進程,但強制鎖起了作用。

        英文原文:Lakshmanan Ganapathy    編譯:伯樂在線 – 肖翔

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!