Linux 系统编程--fcntl()读写锁实例

2023-10-27

在多进程对同一个文件进行读写访问时,为了保证数据的完整性,有事需要对文件进行锁定。可以通过fcntl()函数对文件进行锁定和解锁。

1. fcntl

1.1 功能描述:根据文件描述词来操作文件的特性。

1.2 用法:

int fcntl(int fd, int cmd); 
int fcntl(int fd, int cmd, long arg); 
int fcntl(int fd, int cmd, struct flock *lock); 

fd:文件描述词。 
cmd:操作命令。 
arg:供命令使用的参数,是否需要arg参数跟cmd命令有关。 
lock:锁信息。

2. 读写锁实例

新建两个文件,源码如下2.1、2.2所示。

2.1 给文件加读锁

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

int main(int argc, const char * argv [ ])
{
    int fd = open("test.c", O_RDONLY);
    if (fd == -1)
    {
        perror("open failed:");
        return -1;
    }
    struct stat sta;
    fstat(fd,&sta);

    struct flock lock;   
    lock.l_len = sta.st_size;
    lock.l_pid = getpid();
    lock.l_start = 0;
    lock.l_type = F_RDLCK;
    lock.l_whence = SEEK_SET;

    printf("进程pid: %d\n",lock.l_pid);

    if(fcntl(fd,F_SETLK,&lock) == -1)
    {
        perror("fcntl fail ");
        return -1;
    }
    else
    {
        printf("add read lock success!\n");
    }

    sleep(10);
    close(fd);
    return 0;    
}


2.2 给文件加写锁

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

int main(int argc, const char * argv [ ])
{
    int fd = open("test.c", O_WRONLY);
    if (fd == -1)
    {
        perror("open failed:");
        return -1;
    }
    struct stat sta;
    fstat(fd,&sta);

    struct flock lock;   
    lock.l_len = sta.st_size;
    lock.l_pid = getpid();
    lock.l_start = 0;
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;

    printf("进程pid: %d\n",lock.l_pid);

    while(fcntl(fd,F_SETLK,&lock) == -1 )
    {
        perror("fcntl:");
        sleep(1);
        struct flock lock_1;
        lock_1 = lock;
        lock_1.l_type = F_WRLCK;  //
        fcntl(fd,F_GETLK,&lock_1);//获取文件锁状态,及加锁(lock_1.l_type)能否成功
        switch(lock_1.l_type)
        {
            case F_RDLCK:
                printf("检测到读锁 pid = %d \n",lock_1.l_pid);
                break;
            case F_WRLCK:
                printf("检测到写锁 pid = %d \n",lock_1.l_pid);
                break;
            case F_UNLCK:
                printf("检测到已解锁.pid = %d \n",lock_1.l_pid);
        }
    }
    printf("写锁设置成功\n");
    getchar();
    close(fd);
    return 0;    
}
/*
注意:
1、fcntl(fd,F_GETLK,&lock_1)中的lock_1必须进行初始化,并且lock_1.l_type必须设置为相应的锁,才能确定能否加锁成功,及不成功的原因。
2、GETLK时,fcntl先检测有没有能阻止本次加锁的锁,如果有,则覆盖flock结构体(lock_1)的信息。如果没有,则置lock_1.l_type 的类型为F_UNLCK。
*/

对于写锁(F_WRLCK 独占锁),只有一个进程可以在文件的任一特定区域上享有独占锁。
对于读锁(F_RDLCK 共享锁),许多不同的进程可以同时拥有文件上同一区域上的共享锁。为了拥有共享锁,文件必须以读或者读/写的方式打开。只要任一进程拥有共享锁,那么其他进程就无法再获得独占锁。

分别编译执行:

3. 先执行读锁,再执行写锁。结果如下:

liu@ubuntu:~/learn/lrn_linux$ ./readlock.out 
进程pid: 16458
add read lock success!

liu@ubuntu:~/learn/lrn_linux$ ./writelock.out 
进程pid: 16459
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到读锁 pid = 16458 
fcntl:: Resource temporarily unavailable
检测到已解锁.pid = 16459 
写锁设置成功

可以看出,当文件被读锁占用时,无法添加写锁(独占锁)

4. 先运行写锁,再运行读锁的话,结果如下:

liu@ubuntu:~/learn/lrn_linux$ ./writelock.out 
进程pid: 16349
写锁设置成功

liu@ubuntu:~/learn/lrn_linux$ ./readlock.out 
进程pid: 16350
fcntl fail : Resource temporarily unavailable

所以,加锁是成功的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 系统编程--fcntl()读写锁实例 的相关文章

随机推荐

  • IPv6详解

    定义 128bit冒号分16进制 详解 2001 5 23位 24 32位 33 48位 49 64位 固定开头 regisrty isp prefix site prefix subnet prefix 地址类型 设备没有获取ipv6地址
  • 计算机编码发展历史和编码方式

    编码是信息从一种形式或格式转换为另一种形式的过程 也称为计算机编程语言的代码简称编码 用预先规定的方法将文字 数字或其它对象编成数码 或将信息 数据转换成规定的电脉冲信号 编码在电子计算机 电视 遥控和通讯等方面广泛使用 解码 是编码的逆过
  • 【Seq2Seq】卷积序列到序列学习

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • c#之sealed关键字

    using System using System Collections Generic using System Linq using System Text using System Threading Tasks namespace
  • 仙境传说RO:NPC对话

    仙境传说RO NPC对话 mes next close函数用法详解 大家好 我是艾西 今天跟大家讲解下仙境传说mes next close函数 在游戏中所有的NPC对话都是用mes函数来创建的 我们先打开官方文档的script comman
  • win10系统打开文件安装软件总是弹出安全警告解决办法

    描述 win10系统打开文件安装软件总是弹出安全警告解决办法 步骤 win键 R 输入gpedit msc 点击用户配置 gt 管理模板 gt windows组件 gt 附件管理器文件夹 找到右侧的窗口中找到中等风险文件类型的包含列表设置
  • DemuxException: type = CodecUnsupported, info = Flv: Unsupported codec in video frame: 2

    使用ffmpeg推流到nginx服务器 带http flv module插件 ffmpeg re i rtsp admin qwer1234QWER 10 0 10 3 554 h264 ch1 sub av stream f flv rt
  • 2021-01-05

    c语言 郝斌 p141 malloc函数介绍 include
  • Swagger类的配置

    1 引入相关依赖
  • 华为OD机试 - TLV解析 Ⅱ(Java)

    题目描述 两端通过TLV格式的报文来通信 现在收到对端的一个TLV格式的消息包 要求生成匹配后的 tag length valueOffset 列表 具体要求如下 1 消息包中多组tag length value紧密排列 其中tag len
  • python基础:Python判断文件是否存在的三种方法(os.path.exsist, os.path.isfile, try-catch)

    博客原文 http www spiderpy cn blog detail 28 目录 前言 一 使用os模块 二 使用try catch 前言 通常在读写文件之前 需要判断文件或目录是否存在 不然某些处理方法可能会使程序出错 所以最好在做
  • robot framework实现web和app自动化

    前言 本文 仅适用于完全没接触过rf的小白 也是作为自己学习的一个记录 一 工欲善其事必先利其器 第一步 环境安装 1 需要python环境 去官网下载python解释器 配置环境变量 2 安装robotframework pip inst
  • Python如何实现自动发送直播弹幕,让美女主播一眼看到你

    前言 嘀嘀嘀 你喜欢的女主播开始直播了 咱就是说 时隔两个月 我又回来了 这次不是忘记密码 而是直接忘记这个账号了哈哈 报一丝啊报一丝 不过这次我真的就是会常更新的 因为看到后台还是有小伙伴私信我的 结果才看到信息 每次看直播 不知道大家有
  • C语言--数组&指针笔试题解析(指针:你看我几分像从前)

    尊贵的各位大厂码农你们好 是的 没错 我又来找你们来帮我指正文章了 今天的主题是数组和指针的笔试题专栏 大家给掌掌眼 有问题的话还请帮忙斧正哦 目录 前言 一 数组笔试题 一 一维数组 二 字符数组 2 1 直接赋值型的字符数组 2 2 字
  • 人体姿态2019(四)SemGCN——Semantic Graph Convolutional Networks for 3D Human Pose Regression

    Semantic Graph Convolutional Networks for 3D Human Pose Regression 论文解读 Abstract 1 Introduction 2 Related work 3 Semanti
  • opencv3.4.1mat和Iplimage*互转

    opencv3 4 1mat和Iplimage 互转 Mat转IplImage Mat Img imread 1 jpg IplImage pBinary IplImage Img 浅拷贝 IplImage input cvCloneIma
  • 88 扑克牌大小

    题目描述 扑克牌游戏大家应该都比较熟悉了 一副牌由54张组成 含3 A 2各4张 小王1张 大王1张 牌面从小到大用如下字符和字符串表示 其中 小写joker表示小王 大写JOKER表示大王 3 4 5 6 7 8 9 10 J Q K A
  • Shiro实战学习笔记(3)- 授权

    1 授权 授权可简单理解为who对what which 进行How操作 Who 即主体 Subject 主体需要访问系统中的资源 What 即资源 Resource 如系统菜单 页面 按钮 类方法 系统商品信息等 资源包括资源类型和资源实例
  • CSDN、博客园、简书、思否、掘金,程序员最佳中文论坛我该怎么选

    一 技术论坛有哪些 目前市面上最大的技术论坛主要分为五个 CSDN 博客园 简书 思否 掘金 1 1 CSDN CSDN是全球知名中文IT技术交流平台 创建于1999年 包含原创博客 精品问答 职业培训 技术论坛 资源下载等产品服务 提供原
  • Linux 系统编程--fcntl()读写锁实例

    fcntl 1 功能描述根据文件描述词来操作文件的特性 2 用法 读写锁实例 1 给文件加读锁 2 给文件加写锁 先执行读锁再执行写锁结果如下 先运行写锁再运行读锁的话结果如下 在多进程对同一个文件进行读写访问时 为了保证数据的完整性 有事