Chinaunix首页 | 论坛 | 博客
  • 博客访问: 218479
  • 博文数量: 71
  • 博客积分: 1420
  • 博客等级: 上尉
  • 技术积分: 952
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-11 14:26
文章存档

2009年(16)

2008年(55)

我的朋友

分类: LINUX

2008-04-15 21:08:15

一.记录锁

1.记录锁的功能

       当一个进程正在读或修改文件的某个部分时,它可以阻止其他进程修改同一文件区。我们不应该从字面上去理解记录锁,实际上它应该叫“区域锁”,因为它锁定的只是文件的一个(也可能是整个文件)。这个区域用来存放多用户的共享区。

2.记录锁的分类

       记录锁分为共享读锁和独占写锁,前者也叫做共享锁后者也叫做排他锁。

3.加锁规则

      如果一个进程对共享区加了共享读锁,其他进程只能加共享读锁。如果一个进程加了独占写锁,其他进程就不能加任何锁。

4.死锁

       如果两个相互等待对方持有并且不释放(已被锁定)的资源是时,则这两个进程就处于死锁状态。如果一个进程已经控制了文件的一个加锁区域,然后它又试图对另一个进程控制的区域加锁,则它就会睡眠,在这种情况下,有发生死锁的可能性。

5.锁的隐含继承和释放

1)锁与进程和文件两方面有关系,它和前者关系是:当一个进程结束后,他对文件加的锁也就消失了。它和后者的关系是:当进程close文件描述符,切断文件和进程的联系进程所创建的锁也会消失。

2)由fork产生的子进程不继承父进程所设置的锁。这意味着,若一个进程得到一把锁,然后调用fork,那么对于父进程创建的锁而言,子进程被视为另一个进程,不会拥有该锁。

3)在执行exec后,新进程可以继承原执行的锁。因为执行exec前后还是一个进程。我们只是改变进程执行的程序,并没有创建新的进程。

6.要注意的问题

    记录锁只是提供竞争进入某段代码区的功能,不会导致对文件操作失败。也就是说,我们对文件进行加锁后,我们还是可以对文件进行操作。

 

1

名称:

fcntl

功能

对文加解锁。

头文件

#include

函数原形

int fcntl(int filedes,int cmd,…/*struct flock *flockptr */)

参数

filedes   文件描述符

cmd     测试锁或加锁

flockptr  指向flock结构的指针

返回值:

若成功返回0,若失败返回错误编号。

      

 

 

 

 对于记录锁,cmdF_GETLK,F_SETLKWF_SETLKW.

       F_GETLK判断由flockptr所描述的锁是否会被另外一把锁排斥。如果存在一把锁,他阻止创建由flockptr所描述的锁,则把该现存锁的信息写到flockptr指向的结构中。如果不存在这种情况除了将l_type设置为F_UNLCK之外,flockptr所描述的其他信息都不变。

F_SETLKF_SETLKW企图建立一把锁。F_SETLKF_SETLKW的区别是F_SETLKWF_SETLK的阻塞版本。如果存在其他锁,调用的进程就被阻塞直道捕捉到信号。

       第三个参数是一个指向flock结构的指针:

struct flock{

       short l_type;

       off_t l_start;

       shout l_whence;

       off_t l_len;

       pid_t l_pid;

};

flock结构说明:

所希望的锁类型:F_RDLCK(共享读锁)F_WRLCK(独占性写锁)F_UNLCK(解锁一个区域),这是由 l_type决定的。

要加锁或解锁区域的起始字节偏移量,这是由l_stattl_whence两者决定。

区域的字节长度,由l_len表示。

具有能阻塞当前进程的锁,其持有的ID存放在l_pid中。

       如若l_len0,则表示锁的区域从其起点(由l_startl_whence决定)开始直至最大可能位置为止。也就是不管添写到该文件中多少数据,它都处于的范围。

       如果想锁住整个文件,通常的方法是将l_start说明为0l_whence说明为SEEK_SET1_len说明为0

       还要注意的是,对文件加共享读锁时文件应以只读的方式打开,对文件加独占写锁时文件应以只读的方式打开。

下面是给一个文件加锁和测试锁的程序。

/*12_1.c加锁程序*/

#include

#include

 

int main(int argc,char *argv[])

{

int fd;

struct flock lock;

 

if((fd=open(argv[1],O_WRONLY))<0)

    perror(argv[1]);

lock.l_type=F_WRLCK; /*设置flock结构*/

lock.l_start=0;

lock.l_whence=SEEK_SET;

lock.l_len=0;

 

if(fcntl(fd,F_SETLK,&lock)<0) /*加锁整个文件*/

{

    perror(argv[1]);

    exit(1);

}

sleep(10);

close(fd);

exit(0);

}

 

/*12_2.c测试锁程序*/

#include

#include

 

int main(int argc,char *argv[])

{

int fd;

struct flock lock;

char buf[]=”123456”;

 

if((fd=open(argv[1],O_WRONLY))<0)

    perror(argv[1]);

lock.l_type=F_WRLCK; /*设置flock结构*/

lock.l_start=0;

lock.l_whence=SEEK_SET;

lock.l_len=0;

 

if(fcntl(fd,F_SETLK,&lock)<0)/*测试共享资源是否加锁*/

{

    perror(argv[1]);

    exit(1);

}

if(lock.l_type==F_UNLCK)

    printf(“Is not clocked!\n”);

else

    printf(“Is clocked!\n”);

if(write(fd,buf,sizeof(buf))<0)

    perror(“wrire error”);

close(fd);

exit(0);

}

 

先在后台运行加锁程序

#./12_1 12_1.c&

然后在十秒之内运行测试锁的程序

#./12_2 12_1.c

在屏幕上会打印Is clockd!

如果等待1012_1.c运行完

再次运行测试锁的程序则会打印Is not clocked!

 

这里没有给解锁的程序,大家可以试着去编一编。

阅读(628) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~