文件锁经常应用于两个方面:
1.一是锁定文件中的临界数据,比如并发投票时文件记录的投票数2.二是利用具有互斥性质的写锁,实现进程的并发控制。

/*使用文件锁*/<F5>
#include <fcntl.h>

fcntl(int fildes,int cmd,struct flock* arg);
cmd:F_GETLK,F_SETLK,F_SETLKW
获得或设置记录锁。
如果出错,所有命令都返回-1.

在fcntl.h中的锁信息结构
struct flock
{
    /*锁类型*/
    short l_type;//取值为读锁F_RDLCK,写锁F_WRLCK,释放锁F_UNLCK
    /*锁区域的开始位置*/
    short l_whence;//锁区域开始地址的相对位置,取值为SEEK_SET,SEEK_CUR,SEEK_END
    long l_start;//锁区域万开始地址的偏移量,与l_whence共同确定锁区域的绝对开始位置
    /*锁区域的长度*/
    long l_len;//如果为0,则表示锁至文件末
    /*拥有锁的进程的ID号*/
    short l_pid;
}

F_GETLK: 在申请文件锁之前查找锁信息。
当制定区域中存在多个文件锁时,fcntl只返回其一。
调用成功返回任意非负整数,否则返回-1
用户提交申请的锁类型,函数返回与该锁类型不兼容的锁信息。
如果提交读锁,fcntl只返回该区域内的写锁而忽略读写。因为读锁只与写锁不兼容
如果提交写锁,fcntl只返回区域内的全部锁信息。因为写锁与其他任意锁都不兼容
如果区域内无文件锁时,arg指向的flock结构的成员l_type将被置为F_UNLCK。

所以使用写锁来测试判断文件某块区域内是否已经有现存锁。

F_SETLK:设置读锁,写锁,清除锁。
调用失败返回-1,否则返回其他值。
如果本进程在该区域已经申请锁,则新锁取代该区域的老锁
如果该区域已被其他进程加锁,而且与新锁不兼容,则函数会调用失败。

F_SETLKW:
为F_SETLK的阻塞版,设置读锁,写锁,清除锁,但是会此阻塞版会导致进程阻塞直到请求被完成为止。而F_SETLK会在执行失败时会立刻返回。

使用流程:将测试锁,申请锁,释放锁三块儿封装成三个函数调用,,封装为库函数会使得以后的使用简单方便许多。
测试锁:查询文件描述符对应文件的锁信息,判断是否有不兼容已存锁

1.封装测试锁函数:void SeekLock(int fd,int start,int len);
功能:判断文件描述符对应的文件从文件开始处偏移start处开始的len字节区域中的锁信息:
void SeekLock(int fd,int start,int len)
{
    struct flock arg;
    arg.l_type = F_WRLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = start;
    arg.l_len = len;
    if(fcntl(fd,F_GETLK,&arg) == -1)
    {
        fprintf(stderr,"See Lock failed.\n");
    }
    else if(arg.l_type == F_UNLCK)
    {
        fprintf(stderr,"No lock from %d to %d\n",start,len);
    }
    else if(arg.l_type == F_WRLCK)
    {
        fprintf(stderr,"Write Lock From %d to %d,id = %d\n",start,len,arg.l_pid);
    }
    else if(arg.l_type == F_RDLCK)
    {
        fprintf(stderr,"Read Lock From %d To %d,id = %d\n",start,len,arg.l_pid);
    }
}

2.封装申请读锁函数
void GetReadLock(int fd,int start,int len);
已阻塞模式在文件描述符对应的文件中申请共享读锁,锁定的区域为从偏移start处开始的len字节长度大小的区域

void GetReadLock(int fd,int start,int len)
{
    struct flock arg;
    arg.l_type = F_RDLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = start;
    arg.l_len = len;
    if(fcntl(fd,F_SETLKW,&arg) == -1)
    {
        fprintf(stderr,"[%d] Set Read Lock failed.\n",getpid());
    }
    else
        fprintf(stderr,"[%d] Set Read Lock From %d To %d\n",getpid(),start,len);
}

3.封装申请设置写锁函数
互斥写锁申请函数GetWriteLock,原型为:
void GetWriteLock(int fd,int start,int len)
功能:已阻塞模式在文件描述符对应的文件中申请互斥写锁,锁定的区域为从偏移start处开始的len字节长度大小的区域。

void GetWriteLock(int fd,int start,int len)
{
    struct flock arg;
    arg.l_type = F_WRLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = start;
    arg.l_len = len;
    if(fcntl(fd,F_SETLKW,&arg) == -1)
    {
        fprintf(srderr,"[%d] Set Write Lock failed.\n",getpid());
    }
    else
        fprintf(stderr,"[%d] Set Write Lock %d To %d\n",getpid(),start,len);
}

}
}

4.释放锁
void ReleaseLock(int fd,int start,int len)
{
    struct flock arg;
    arg.l_type = F_UNLCK;
    arg.l_whence = SEEK_SET;
    arg.l_start = start;
    arg.l_len = len;
    if(fcntl(fd,F_SETLKW,&arg) == -1)
    {
        fprintf(stderr,"[%d] Unlock failed.\n",getpid());
    }
    else
        fprintf(stderr,"[%d]Unlock From %d To %d\n",getpid(),start,len);
}

fcntl文件锁操作的更多相关文章

  1. 高级IO

    # 高级IO 特殊的IO操作,包括文件锁.系统V的流.信号驱动的I/O.多路转I/O(select和pull函数).readv和writev函数以及存贮映射I/O等概念和函数. ## 文件锁 文件锁是 ...

  2. Linux 系统 文件锁 fcntl函数详解

    #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd); int fcntl(int fd, int ...

  3. Linux文件(区域)锁函数 -- open()、fcntl()

    一.什么是文件锁定 对于锁这个字,大家一定不会陌生,因为我们生活中就存在着大量的锁,它们各个方面发挥着它的作用,现在世界中的锁的功能都可归结为一句话,就是阻止某些人做某些事,例如,门锁就是阻止除了屋主 ...

  4. 每天进步一点点——Linux文件锁编程flock

    转载请注明出处:http://blog.csdn.net/cywosp/article/details/30083015 1. 场景概述     在多线程开发中.相互排斥锁能够用于对临界资源的保护,防 ...

  5. 文件I/O实践(3) --文件共享与fcntl

    文件共享 一个进程打开了两个文件 文件表条目(file-table-entry): 1.文件状态标志(file-status-flags): 读/写/追加/同步/非阻塞等; 2.当前文件偏移量 3.v ...

  6. SQLite3命令操作大全

    SQLite3命令操作大全 SQLite库包含一个名字叫做sqlite3的命令行,它可以让用户手工输入并执行面向SQLite数据库的SQL命令.本文档提供一个样使用sqlite3的简要说明. 一.ql ...

  7. fcntl函数用法详解

    功能描述:根据文件描述词来操作文件的特性. #include <unistd.h> #include <fcntl.h>  int fcntl(int fd, int cmd) ...

  8. linux文件锁flock【转】

    转自: https://www.cnblogs.com/kex1n/p/7100107.html linux文件锁flock   在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要 ...

  9. fcntl详细说明

    功能描述:根据文件描述词来操作文件的特性. #include <unistd.h>#include <fcntl.h> int fcntl(int fd, int cmd);  ...

随机推荐

  1. RabbitMQ理论部分

    概念 queue        队列 exchange   交换机 bind          绑定 channel     通道 一个发送消息流程包含上述四个概念.消息经过channel传递给exc ...

  2. 【Py大法系列--01】20多行代码生成你的微信聊天机器人

    前言 近期Stack Overflow公布了一项调查显示,Python已经成了发展最快的主流编程语言,Python搭乘着数据科学和机器学习以及人工智能的浪潮,席卷了整个技术圈.越来越多的人想了解.想学 ...

  3. Description Resource Path Location Type Cannot change version of project fac

    http://www.cnblogs.com/eaysun/p/5661631.html

  4. 详解HTTP缓存

    HTTP缓存是个大公司面试几乎必考的问题,写篇随笔说一下HTTP缓存. 1. HTTP报文首部中有关缓存的字段 在HTTP报文中,与缓存相关的信息都存在首部里,简单说一下首部. 首部 HTTP首部字段 ...

  5. 《Java学习笔记JDK8》学习总结

    chapter 6   继承与多态 6.1何谓继承 1.继承的定义:继承就是避免多个类间重复定义共同行为. 2.总结:教材中通过设计一款RPG游戏的部分代码向我们展示了“重复”程序代码的弊端,为了改进 ...

  6. 20162328蔡文琛 week11 大二

    20162328 2017-2018-1 <程序设计与数据结构>第十一周学习总结 教材学习内容总结 在无向图中,表示边的顶点对是无序的. 如果图中的两个顶点之间有边链接,则称它们是领接的. ...

  7. P2P通讯原理

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

  8. 课堂练习 psp表

    项目计划总结表: 日期 编程 完善程序 测试程序 参考资料 日总结 3.20 18:00---19:30       1.5 3.21   9:30----10:00 10:00---10:30   ...

  9. Spring笔记⑤--整合hibernate代码测试

    String整合hibernate代码测试 在上节生成的表中插入数据:   注意:使用myeclipse2014生成的整合项目可能存在问题需要我们自己导入.   第一步 我们写dao接口 packag ...

  10. <mvc:annotation-driven/>的作用

    <mvc:annotation-driven>的作用是: 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapt ...