linux命令解锁 linux加锁解锁( 三 )


成员l_whence、l_start和l_len定义了一个文件中的一个区域 , 即一个连续的字节集合,例如:
struct flock region;
region.l_whence = SEEK_SET;
region.l_start = 10;
region.l_len = 20;
则表示fcntl函数操作锁定的区域为文件头开始的第10到29个字节之间的这20个字节 。
3、文件锁的类型
从上面的flock的成员l_type的取值我们可以知道,文件锁的类型主要有三种,这里对他们进行详细的解说 。
F_RDLCK:
从它的名字我们就可以知道,它是一个读锁,也叫共享锁 。许多不同的进程可以拥有文件同一(或重叠)区域上的读(共享)锁 。而且只要任一进程拥有一把读(共享)锁 , 那么就没有进程可以再获得该区域上的写(独占)锁 。为了获得一把共享锁,文件必须以“读”或“读/写”方式打开 。
简单点来说就是,当一个进程在读文件中的数据时,文件中的数据不能被改变或改写,这是为了防止数据被改变而使读数据的程序读取到错乱的数据,而文件中的同一个区域能被多个进程同时读取,这是容易理解的 , 因为读不会破坏数据,或者说读操作不会改变文件的数据 。
F_WRLCK:
从它的名字,我们就可以知道,它是一个写锁,也叫独占锁 。只有一个进程可以在文件中的任一特定区域拥有一把写(独占)锁 。一旦一个进程拥有了这样一把锁 , 任何其他进程都无法在该区域上获得任何类型的锁 。为了获得一把写(独占)锁,文件也必须以“读”或“读/写”方式打开 。
简单点来说,就是一个文件同一区域(或重叠)区域进在同一时间,只能有一个进程能对其进行写操作,并且在写操作进行期间,其他的进程不能对该区域进行读取数据 。这个要求是显然易见的 , 因为如果两个进程同时对一个文件进行写操作 , 就会使文件的内容错乱起来 , 而由于写时会改变文件中的数据,所以它也不允许其他进程对文件的数据进行读取和删除文件等操作 。
F_UNLCK:
从它的名字就可以知道,它用于把一个锁定的区域解锁 。
4、不同的command的意义
在前面说到fcntl函数的command参数时,说了三个命令选项,这里将对它们进行详细的解说 。
F_GETLK命令,它用于获取fildes(fcntl的第一个参数)打开的文件的锁信息,它不会尝试去锁定文件,调用进程可以把自己想创建的锁类型信息传递给fcntl,函数调用就会返回将会阻止获取锁的任何信息 , 即它可以测试你想创建的锁是否能成功被创建 。fcntl调用成功时,返回非-1,如果锁请求可以成功执行,flock结构将保持不变 , 如果锁请求被阻止,fcntl会用相关的信息覆盖flock结构 。失败时返回-1 。
所以,如果调用成功 , 调用程序则可以通过检查flock结构的内容来判断其是否被修改过,来检查锁请求能否被成功执行,而又因为l_pid的值会被设置成拥有锁的进程的标识符,所以大多数情况下,可以通过检查这个字段是否发生变化来判断flock结构是否被修改过 。
使用F_GETLK的fcntl函数调用后会立即返回 。
举个例子来说 , 例如 , 有一个flock结构的变量,flock_st,flock_st.l_pid = -1,文件的第10~29个字节已经存在一个读锁,文件的第40~49个字节中已经存在一个写锁 , 则调用fcntl时,如果用F_GETLK命令,来测试在第10~29个字节中是否可以创建一个读锁,因为这个锁可以被创建,所以,fcntl返回非-1,同时,flock结构的内容也不会改变,flock_st.l_pid = -1 。而如果我们测试第40~49个字节中是否可以创建一个写锁时,由于这个区域已经存在一个写锁,测试失败,但是fcntl还是会返回非-1,只是flock结构会被这个区域相关的锁的信息覆盖了 , flock_st.l_pid为拥有这个写锁的进程的进程标识符 。

推荐阅读