linux记录锁(范围锁)

来源:互联网 发布:知乎什么时候成立的 编辑:程序博客网 时间:2024/06/06 03:53

fcntl函数原型如下:int fcntl(int fd, int cmd, ... /* struct flock *arg */);  包含在<fcntl.h>中。

第三个参数是指向flock类型的指针:

struct flock
{
    short l_type;   /* F_RDLCK, F_WRLCK, F_UNLCK */
    short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start;  /* relative starting offset in bytes */
    off_t l_len;    /* #bytes; 0 means until end-of-file */
    pid_t l_pid;    /* PID return by F_GETLK */
};

cmd参数有三个值:

F_SETLK:获取或释放由arg指向的flock结构所描述的锁,若无法获取锁,则立刻返回一个EACCES或EAGAIN错误而不阻塞。
F_SETLKW :与F_SETLK不同的是,如果无法获取的锁,将阻塞直到获取锁为止,W即wait
F_GETLK:检查由arg指向的锁以确定是否有某个已存在的锁。若不存在锁在将arg指向的l_type成员设置为F_UNLCK,若存在锁,则返回arg所指向的flock结构信息。

flock结构描述锁的类型(读出锁或写入锁)以及待锁住的字节范围。锁定整个文件的两种方法:

1)指定l_whence成员为SEEK_SET,l_start成员为0,l_len成员为0。(最常用方法)

2)使用lseek把读写指针定位到文件,然后指定l_whence成员为SEEK_CUR、l_start成员为0,l_len成员为0。

注意:

对于一个打开着某个文件的给定进程来说,当它关闭该文件的所有描述符它本身终止时,与该文件关联的所有锁都被删除。

锁不能通过fork由子进程继承。

单进程时,对文件加锁,新锁会代替已有的锁。

当前区域无锁,可加读锁 或 可加写锁;

当前区域读锁,可加读锁 或 不可加写锁;

当前区域写锁,不可加读锁 或 不可加写锁;

 

当前区域多读一写;

 

#define read_lock(fd,offset,whence,len)                lock_reg(fd,F_SETLK,F_RDLCK,offset,whence,len) 

#define readw_lock(fd,offset,whence,len)              lock_reg(fd,F_SETLKW,F_RDLCK,offset,whence,len)

#define write_lock(fd,offset,whence,len)               lock_reg(fd,F_SETLK,F_WRLCK,offset,whence,len) 

#define writew_lock(fd,offset,whence,len)             lock_reg(fd,F_SETLKW,F_WRLCK,offset,whence,len) 

#define un_lock(fd,offset,whence,len)                  lock_reg(fd,F_SETLK,F_UNLCK,offset,whence,len)  

#define is_read_lockable(fd,offset,whence,len)         !lock_test(fd,F_RDLCK,offset,whence,len) 

#define is_write_lockable(fd,offset,whence,len)        !lock_test(fd,F_WRLCK,offset,whence,len) 

int lock_reg(int fd,int cmd,int type,off_t offset,int whence,off_t len)

 {

struct flock lock;

lock.l_type = type;

lock.l_start = offset;

lock.l_whence = whence;

lock.l_len = len;

  return (fcntl(fd,cmd,&lock));

 }

 

pid_t lock_test(int fd,int type,off_t offset,int whence,off_t len)

{   struct flock lock;

     lock.l_type = type;

     lock.l_start = offset;

     lock.l_whence = whence;

     lock.l_len = len;

     if(fcntl(fd,F_GETLK,&lock) == -1)

     {         return (-1);//error     }

       //region is not locked
     if(lock.l_type == F_UNLCK)

         return (0);

     return (lock.l_pid);

 }

 

 

原创粉丝点击