`

Linux中的两种文件锁—协同锁与强制锁

 
阅读更多

转自 http://blog.jobbole.com/16882/

 

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

在这篇文章中,我们将探讨Linux中不同类型的文件锁,并通过示例程序来理解它们之间的不同之处。

我们将采取以下的例子来解释为什么需要使用文件锁。

1、  进程“A”打开和读取一个文件,此文件包含账户相关的一些信息。

2、  进程“B”也打开了这个文件,并读取了文件中的信息。

3、  现在,进程“A”更改了其副本中的一条余额记录,并将其写入文件。

4、  此时,进程“B”并不知道上次读取的文件已经被更改,它还保存着原始的文件副本。然后,进程“B”更改了“A”操作的那条相同的记录,并将记录写入文件。

5、  此时,文件中将只保存了进程“B”更改过的记录。

为了避免这种事情发生,就要使用文件锁来确保操作的“序列化”。

 

以下是Linux系统中两种常用的文件锁:

1、  协同锁

2、  强制锁

2 Types of Linux File Locking

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>
 
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,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中的协同锁与强制锁

    ### Linux中的协同锁与强制锁 #### 一、引言 在多进程环境中,文件的并发访问可能会导致数据不一致的问题。例如,当多个进程同时读写同一个文件时,如果没有适当的同步机制,可能会出现数据冲突或者丢失的情况。...

    linux文件锁flock

    总之,`flock`作为一种高效的文件锁机制,在Linux系统中被广泛应用于需要控制共享文件访问的各种场景中。理解其工作原理及其与`fcntl`的区别有助于更好地利用这些工具来提高程序的健壮性和效率。

    linux文件锁的使用

    linux文件锁的使用linux文件锁的使用

    Linux编程下的fcntl文件锁代码

    在文件锁中,有两类锁:共享锁(读锁)和独占锁(写锁)。共享锁允许多个进程同时读取文件,而独占锁只允许一个进程写入文件。 现在,我们来看看提供的源代码示例: - **lock_set.c**:这个文件可能包含了一个示例...

    linux守护进程加排它锁文件锁

    在linux下实现守护进程并加上排它锁(文件锁),避免重复启动进程

    一种Linux内核自旋锁死锁检测机制的设计与实现.pdf

    自旋锁是一种锁机制,通过不停自旋来获得锁。自旋锁的使用可以大幅提高系统性能和吞吐量,但同时也存在着一定的风险。如果自旋锁的使用不当,CPU 会陷入死循环,导致系统死锁。 在 Linux 内核中,自旋锁的使用非常...

    svn强制解锁

    svn强制解锁svn强制解锁svn强制解锁svn强制解锁svn强制解锁svn强制解锁

    Qt加锁操作、文件锁、生产消费锁GUI演示

    在本文中,我们将深入探讨如何在Qt环境中使用线程锁,包括文件锁和生产者-消费者锁,并结合Visual Studio 2019进行GUI编程。这些知识点对于理解多线程同步以及Qt GUI应用的开发至关重要。 首先,让我们从Qt中的线程...

    windows和linux读写锁C++实现

    在多线程编程中,读写锁是一种非常重要的同步机制,它允许多个读线程同时访问共享资源,但只允许一个写线程独占资源,从而提高了并发性能。本话题将详细探讨在Windows和Linux环境下,如何使用C++来实现读写锁。 ...

    Linux系统对文件进行加锁

    总之,Linux中的Flock函数为多线程环境下的文件访问提供了安全的保护措施,通过设置锁来防止并发写入导致的问题。正确使用Flock可以帮助开发者构建可靠的多进程应用程序,保证数据一致性,并避免潜在的竞态条件。...

    文件锁,很好用的一个东西

    文件锁的实现通常依赖于操作系统提供的API,如在Unix/Linux系统中,可以使用fcntl()函数的F_SETLK和F_SETLKW标志来设置锁;在Windows系统中,可以使用CreateFile()函数配合LockFileEx()或UnlockFileEx()来实现。这些...

    linux系统中基于自旋锁的进程调度的实现

    在Linux内核中,自旋锁的实现分为两种:可中断自旋锁(Interruptible Spin Locks)和不可中断自旋锁(Non-Interruptible Spin Locks)。可中断自旋锁允许等待锁的进程在自旋过程中被硬件中断,这样它们可以在等待...

    linux文件和记录锁[借鉴].pdf

    在Linux系统中,文件和记录锁是用于管理多个进程对同一文件访问的重要机制,确保数据的一致性和完整性。这两种锁定方式允许程序控制对文件的并发访问,防止数据冲突。 首先,我们要理解文件锁(File Locks)和记录...

    linux文件读写锁实例C代码

    linux文件读写锁一个例子,已经通过测试,使用非常方便

    文件锁,用于锁住自己的隐私文件

    文件锁是一种重要的安全措施,主要用于保护用户的个人隐私和敏感数据,防止未经授权的访问或修改。在计算机系统中,文件锁的应用十分广泛,特别是在多用户环境下,确保数据的一致性和完整性。这个“文件锁”程序是你...

    库存上锁(文件锁+redis.pdf

    标题中的“库存上锁(文件锁+redis)”是指在分布式系统中,为了保证库存操作的并发一致性,采用的一种复合型锁机制。这种机制结合了文件锁和Redis缓存服务来实现分布式锁的功能。 分布式锁是在多节点环境下,用于...

    加密文件使用的X-文件锁

    【加密文件技术与X-文件锁】 在信息技术领域,数据安全是至关重要的,尤其是在处理敏感信息时,如Word文档等办公文件。为了保护这些文件不被未经授权的访问或篡改,人们常常会采用文件加密技术。X-文件锁就是一种专...

    linux写优先的读写锁设计

    在 Linux 操作系统中,有两种基本机制来实现数据互斥,即信号量(semaphore)和自旋锁(spinlock)。本文将讨论一种特殊的自旋锁变种,即读写锁(read-write lock),它允许多个进程同时访问共享资源,但是写操作...

    linux_锁_原子_自旋

    在Linux操作系统中,锁、原子操作和自旋锁是内核并发控制的重要机制,用于确保多线程环境下的数据一致性与正确性。这些概念在构建高效、可靠的并发程序时至关重要。 **1. Linux锁** Linux内核中的锁主要用于保护...

Global site tag (gtag.js) - Google Analytics