zoukankan      html  css  js  c++  java
  • (转载)Linux中的两种文件锁——协同锁与强制锁

    (转载)http://www.blogjava.net/qileilove/archive/2012/05/23/378903.html

     Linux文件锁的示例

      为了理解文件锁是如何工作的,我们建立程序文件file_lock.c:

     

    #include <stdio.h>
    #include <fcntl.h>
     
    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 = 0;
        lock.l_whence = SEEK_SET;
        lock.l_len = 0;
        lock.l_pid = getpid();
      
        int ret = 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用户才能执行下面的命令。

     

    # 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 mandatory.txt
    # chmod 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文件之前,会等待文件锁被删除。虽然它仍然是一个非合作进程,但强制锁起了作用。

     

     文件锁是一种文件读写机制,在任何特定的时间只允许一个进程访问一个文件。利用这种机制能够使读写单个文件的过程变得更安全。

      在这篇文章中,我们将探讨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)、挂载文件系统时使用“-omand”参数。

      (2)、对于要打开强制锁功能的文件lock_file,必须打开set-group-ID位,关闭group-execute位。(选择此方法的原因是,当你关闭group-execute时,设置set-group-ID就没有实际的意义了)

  • 相关阅读:
    em与rem之间的区别以及移动设备中的rem适配方案
    关于两个DIV之间的空白字符
    Bootstrap基本模板
    js 裁剪
    记一次诡异的bug
    Node切换版本
    git 撤销
    使用 iframe + postMessage 实现跨域通信
    <el-input>标签限制输入小数点
    vue elementyUI table :点击一行时选中这一行对应的复选框
  • 原文地址:https://www.cnblogs.com/Robotke1/p/3056471.html
Copyright © 2011-2022 走看看