• 记录锁


    作用

    记录锁与读写锁很相似, 记录锁也分读和写两种操作, 但它们的作用对象分别是进程和线程.
    多个进程对同一文件进行访问时,记录锁可以锁定文件的某一个区间,以读操作锁定时允许其它进程进行继续加读锁, 以写操作锁定时不允许其它进程添加读锁或写锁.
    记录锁只对加锁的函数fcntl进行检测, 如果其它进程不按先加锁后读写的顺序进行访问则记录锁不起作用.
    在一些系统上将组权限位打开, 同时关闭组执行位可强制所有读写函数进行锁检查.

    基本函数

    #include <fcntl.h>
    int fcntl(int fd, int cmd, struct flock *lock);
    cmd = F_GETLK //获取文件当前锁的状态,第三个参数作为输出
    cmd = F_SETLK //设置锁,第三个参数作为输入
    cmd = F_SETLKW //阻塞设置一把锁,第三个参数作为输入
     
    struct flock {
          short l_type;    /* 锁的类型: F_RDLCK, F_WRLCK, F_UNLCK */
          short l_whence;  /* 加锁的起始位置:SEEK_SET, SEEK_CUR, SEEK_END */
          off_t l_start;   /* 加锁的起始偏移,相对于l_whence */
          off_t l_len;     /* 上锁的字节数*/
          pid_t l_pid;     /* 已经占用锁的PID(只对F_GETLK 命令有效) */
          /*...*/
    };
    

    例子

    #include "unpipc.h"
     
    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_len=len;
        lock.l_type=type;
        lock.l_whence=whence;
        lock.l_len=len;
     
        if(fcntl(fd,F_GETLK,&lock) == -1)
            return(-1);
     
        if(lock.l_type == F_UNLCK)
            return(0);
        return(lock.l_pid);
    }
     
    #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 main(int argc, char *argv[]){
        pid_t pid;
        int fd=Open("./lock.c",O_RDWR,0777);
        if((pid=Fork())==0){
            if(read_lock(fd,0,SEEK_SET,1) == -1)
                err_quit("child read_lock error");
           puts("child read_lock file");
           sleep(3);
           puts("child un_lock file");
           un_lock(fd,0,SEEK_SET,1);
        }else{
            sleep(1);
           if(write_lock(fd,0,SEEK_SET,1) == -1)
               puts("father write_lock failed, waiting for child un_lock");
           if(writew_lock(fd,0,SEEK_SET,1) == -1)
               puts("father writew_lock error");
           puts("father got write lock");
           un_lock(fd,0,SEEK_SET,1);
           waitpid(pid,NULL);
        }
        exit(0);
    }
    
  • 相关阅读:
    关于Web 打印的三种方法
    禁止另存为 禁止复制 禁止右键 JS
    无限数据递归
    VS2003+Ajax Div文本框输入提示
    C#关于日期月天数和一年有多少周及某年某周时间段的计算
    git代码冲突
    RabbitMQ死信队列
    Elementui:ElContainer布局
    mxml调用as
    用自己的MapServer,解决沙箱冲突
  • 原文地址:https://www.cnblogs.com/cfans1993/p/5800603.html
Copyright © 2020-2023  润新知