六、Linux系统编程:读写锁

2023-11-10

5 读写锁

读写锁(ReentrantReadWriteLock)就是读线程和读线程之间不互斥。
读读不互斥,读写互斥,写写互斥

一个资源可以被多个读线程访问,也可以被一个写线程访问,但不能同时存在读写线程,读写互斥,读读共享

5.1 锁操作

int fcntl(int fd, int cmd, struct flock *lock)
  • 参数
参数 含义
fd 文件描述符
cmd 命令。F_GETLK:获取锁;F_SETLK:设置锁;F_SETLKW:设置阻塞锁。
struct flock 锁信息
  • 锁信息
参数 含义
l_type F_RDLCK:读取锁(共享锁);F_WRLCK:写入锁(排斥锁);F_UNLCK:解锁
l_whence SEEK_SET:以文件开头为锁定的起始位置;SEEK_CUR:以目前文件读写位置为锁定的起始位置;SEEK_END:以文件结尾为锁定的起始位置
l_start 相对l_whence位置的偏移量
l_len 锁定区域的长度。0表示到整个文件的结束
l_pid 当前占用锁的PID,只对F_GETLK命令有效
  • 返回值
返回值 含义
-1 失败
0 SET相关命令成功
  • 给指定文件添加读锁
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char* argv[]){
    if(2!=argc){
        printf("usage:%s <pathname>\n",argv[0]);
        return 1;
    }
    int fd = open(argv[1],O_RDONLY);
    if(-1 == fd){
        perror("open error");
        return 1;
    }
    struct flock lock;
    lock.l_type = F_RDLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0; 
    if(-1 == fcntl(fd,F_SETLK,&lock)){
        perror("fcntl error");
        return 1;
    }
    pause();
    close(fd);
}
  • 查看当前锁的状态
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
 
int main(int argc, char* argv[]){
    if(2!=argc){
        printf("usage:%s <pathname>\n",argv[0]);
        return 1;
    }
    int fd = open(argv[1],O_RDWR);
    if(-1 == fd){
        perror("open error");
        return 1;
    }
    struct flock lock;
    bzero(&lock,sizeof(lock));
    if(-1 == fcntl(fd,F_GETLK,&lock)){
        perror("fcntl error");
        return 1;
    }
    printf("file:%s,lock type:%d,start:%d,len:%d,by %d\n",argv[1],lock.l_type,lock.l_start,lock.l_len,lock.l_pid);
 
}
  • 给指定文件添加写锁
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int fd;
 
void handler(int sig){
    struct flock lock;
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0; 
    if(-1 == fcntl(fd,F_SETLKW,&lock)){
        perror("fcntl error");
        exit(1);
    }
}
 
int main(int argc, char* argv[]){
    signal(SIGUSR1,handler);
    int c,start = 0,len = 0;
    while((c = getopt(argc,argv,"s:l:"))!=-1){
        switch(c){
        case 's':
            start = atoi(optarg);
            break;
        case 'l':
            len = atoi(optarg);
            break;
        }
    }
 
    if(optind != argc -1){
        printf("usage:%s [-s <start>] [-l <len>] <pathname>\n",argv[0]);
        return 1;
    }
    fd = open(argv[optind],O_WRONLY);
    if(-1 == fd){
        perror("open error");
        return 1;
    }
    struct flock lock;
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = start;
    lock.l_len = len; 
    if(-1 == fcntl(fd,F_SETLKW,&lock)){
        perror("fcntl error");
        return 1;
    }
    pause();
    for(;;);
    close(fd);
}
  • 给指定文件解锁
// 本程序不能解锁,因为只有加锁进程才能执行解锁操作
#include <stdio.h>
#include <fcntl.h>
 
int main(int argc, char* argv[]){
    if(2!=argc){
        printf("usage:%s <pathname>\n",argv[0]);
        return 1;
    }
    int fd = open(argv[1],O_WRONLY);
    if(-1 == fd){
        perror("open error");
        return 1;
    }
    struct flock lock;
    lock.l_type = F_UNLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0; 
    if(-1 == fcntl(fd,F_SETLKW,&lock)){
        perror("fcntl error");
        return 1;
    }
    pause();
    close(fd);
}

5.2 死锁

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
void lock(const char* pathname){
 
    int fd = open(pathname,O_WRONLY);
    if(-1 == fd){
        perror("open error");
        exit(1);
    }
    struct flock lock;
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0; 
    if(-1 == fcntl(fd,F_SETLKW,&lock)){
        perror("fcntl error");
        exit(1);
    }
    //close(fd);
}
int main(int argc, char* argv[]){
    if(3!=argc){
        printf("usage:%s <pathname1> <pathname2>\n",argv[0]);
        return 1;
    }
    printf("PID:%d lock file %s\n",getpid(),argv[1]);
    lock(argv[1]);
    printf("sleep 1s\n");
    sleep(1);
    printf("PID:%d lock file %s\n",getpid(),argv[2]);
    lock(argv[2]);
    pause();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

六、Linux系统编程:读写锁 的相关文章

随机推荐

  • 平稳过程的各态历经性

    平稳过程的各态历经性 1 各态历经的定义 2 例题 2 1 例1 2 2例2 3 各态历经性的判定 1 各态历经的定义 如果一个随机过程是平稳的 而且是均值和相关函数都具有各态历经性 那么我们称这个平稳过程具有各态历经性 均值各态历经的定义
  • Ubuntu ssh 访问服务器失败

    今天用ssh 登录交换机的时候发现访问不了 一直报no matching key exchange method found ccchw ccchw HP Compaq Elite 8300 CMT ssh ssh itte 10 163
  • K210图像检测&(1~8)数字卡片识别

    前言 第一次使用该平台 想先找一个简单的识别 来走走流程 就想到了 前几年的送药小车的数字卡片识别 花了半天收集标记图片 在运行时要注意摄像头与数字卡片的高度 不过也有些不足 可能是收集某个数字的训练集的时候 拍摄高度 不一致 因为是手拍
  • C++之引用类型,深浅拷贝构造

    引用类型 给内存段取别名 int m 10 引用 给内存段取别名 所以需要给他一段内存段 而不只是声明 int n m 不是赋值的意思 是别名的意思 想要在被调函数中修改主调函数中定义的变量的值时 不需要将其地址传输给被调函数 直接传输变量
  • IDEA 使用技巧(快速生成xml文件)

    settiings 搜索File 找到 File and Code Templates 点击加号新建一个 Name 输入文件名 Extension 输入文件类型
  • PCL 生成空间直线点云

    目录 一 算法原理 二 代码实现 三 结果展示 一 算法原理 已知直线上一点和直线的方向向量 即可根据数学原理生成用于算法测试的标准直线点云 以下示例代码中 以直线上一点为中心点生成空间直线点云 其中点的个数为100个 相邻点之间的间隔为0
  • 微信小程序的的图片显示不出来

    图片的路径分两种 1 本地的图片如images文件夹下面的 images t1 jpg 或者是http localhost 8080 Teacher news t1 jpg 2 网络连接的图片http www baidu com vue n
  • python自动化操作, 三种方法解决滑动模块问题(后二种可跳过90%滑动,限制需要打开浏览器)

    selenium win32api pyautogui 元素定位 可无头进行访问 但是会被检测 基本用不了 sli ele driver find element By XPATH span id nc 1 n1z xpath 定位 if
  • 人工智能电话机器人一个顶10个,各版本系统搭建

    前接触多的就是电销行业 有电话机器人 VOS线路问题或要演示站AI技术支持 一个人面对多台电话不停地接听 特别是客户多时不知道应答哪一个 反而还把自己搞得心烦意乱 不过随着科技的发展 电销行业里出现了一个叫智能电销机器人的产品 自动应答客户
  • Innovus零基础lab学习全面复盘总

    Innovus零基础lab学习全面复盘总结 附完整版pdf 文章右侧广告为官方硬广告 与吾爱IC社区无关 用户勿点 点击进去后出现任何损失与社区无关 为了让各位训练营学员更快入门数字 IC 后端 从第八期 IC 训练营开始 小编以一个 数字
  • chatgpt 上方一直在转圈 白屏 空白

    下面空白 上面有个转圈 清除缓存 进入https platform openai com 返回刷新 更换节点 退出 Clash 软件 返回刷新 白屏 空白 来回换节点 就是换节点 有的时候是v p n的问题
  • MongoDB安装部署

    一 mongodb安装部署 关闭防火墙和selinux root mongodb iptables F root mongodb setenforce 0 root mongodb systemctl stop firewalld 2 指定
  • hdu 3879 最大密集子图(点和边均带权)(模板)

    最大权闭合图 可以用最大密集子图来解速度更快复杂度低 题解 胡伯涛 最小割模型在信息学竞赛中的应用 点和边均带权的最大密集子图 s i 权为U 点权绝对值和 边的所有权值 i t 权为U 点的值 点的度 u v 权值为w 意思是选了v后可以
  • Mybatis-plus使用手册

    Mybatis plus 1 定义 MyBatis Plus 是一个 Mybatis 增强版工具 在 MyBatis 上扩充了其他功能没有改变其基本功能 为了简化开发提交效率而存在 2 使用 SpringBoot 集成 MyBatis Pl
  • 相关性分析

    这里的相关性分析主要是线性相关性分析 当然其他的形状的相关性分析可以通过变换转换为线性相关性分析 但是 线性相关性分析始终是相关性分析的基础 线性相关分析的构建主要分为以下几种 直接绘制散点图 通过把点标出来主观上看是否是线性相关 绘制散点
  • 《动手学深度学习》第二十三天---稠密连接网络(DenseNet)

    一 DenseNet DenseNet作为另一种拥有较深层数的卷积神经网络 具有如下优点 1 相比ResNet拥有更少的参数数量 2 旁路加强了特征 feature 的重用 3 网络更易于训练 并具有一定的正则效果 4 缓解了gradien
  • Android Studio按钮背景色

    Android Studio按钮背景色改变 修改style xml theme xml 在Android Studio里写前端界面 修改Button的背景样式一直是系统默认的主题色就像这样 不管怎么改颜色都会是系统的默认主题色 这里我们需要
  • LC并联谐振电路的原理

    LC并联谐振电路的原理 2011 11 26 04 54 353744594 来自 手机知道 分类 电脑 网络 浏览6573次 LC并联谐振电路的原理 我怎么不能理解这个原理 能不能用生活中的例子来说明 谢谢 提问者采纳 2011 11 2
  • Springboot使用maven打包指定mainClass

    http jvm123 com 2019 12 springboot repackage html
  • 六、Linux系统编程:读写锁

    5 读写锁 读写锁 ReentrantReadWriteLock 就是读线程和读线程之间不互斥 读读不互斥 读写互斥 写写互斥 一个资源可以被多个读线程访问 也可以被一个写线程访问 但不能同时存在读写线程 读写互斥 读读共享 5 1 锁操作