首页 > 系统相关 >Linux系统编程 —读写锁rwlock(转载~)

Linux系统编程 —读写锁rwlock(转载~)

时间:2022-09-01 18:12:01浏览次数:77  
标签:rwlock 加锁 函数 int 读写 Linux pthread

读写锁是另一种实现线程间同步的方式。与互斥量类似,但读写锁将操作分为读、写两种方式,可以多个线程同时占用读模式的读写锁,这样使得读写锁具有更高的并行性。

读写锁的特性为:写独占,读共享;写锁优先级高。对于读写锁,掌握了这12个字就足矣了。

Linux环境下,读写锁具有以下三种状态:

  1. 读模式下加锁状态 (读锁)
  2. 写模式下加锁状态 (写锁)
  3. 不加锁状态

虽然读写锁有读锁、写锁、不加锁三种状态,但其实它只有一把锁,而非三把。

前文提到,读写锁的特性为:写独占,读共享;写锁优先级高。具体来讲:

  1. 读写锁是“写模式加锁”时, 解锁前,所有尝试对该锁进行加锁(不管是读锁还是写锁)的线程都会被阻塞;--> 写独占
  2. 读写锁是“读模式加锁”时, 如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。--> 读共享
  3. 读写锁是“读模式加锁”时, 既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求,优先满足写模式锁。--> 写锁优先级高

读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。写独占、读共享。

读写锁非常适合于对数据结构读的次数远大于写的情况。因为读锁是共享的,这样可以提高并行性。

主要应用函数:

pthread_rwlock_init函数
pthread_rwlock_destroy函数
pthread_rwlock_rdlock函数
pthread_rwlock_wrlock函数
pthread_rwlock_tryrdlock函数
pthread_rwlock_trywrlock函数
pthread_rwlock_unlock函数

以上7 个函数的返回值都是:成功返回0,失败直接返回错误号。

pthread_rwlock_t类型:用于定义一个读写锁变量,比如:pthread_rwlock_t rwlock;

pthread_rwlock_init函数

函数原型:

int pthread_rwlock_init(pthread_rwlock_t restrict rwlock, const pthread_rwlockattr_t restrict attr);

函数作用:

初始化一把读写锁

参数说明:

rwlock:传出参数,调用时应传&rwlock给该函数;

attr:表示读写锁属性,通常传NULL,表示使用默认属性;

pthread_rwlock_destroy函数

函数原型:

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

函数作用:

销毁一把读写锁

pthread_rwlock_rdlock函数

函数原型:

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

函数作用:

以读方式请求读写锁。(常简称为:请求读锁)

pthread_rwlock_wrlock函数

函数原型:

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

函数作用:

以写方式请求读写锁。(常简称为:请求写锁)

pthread_rwlock_unlock函数

函数原型:

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

函数作用:

解锁。

pthread_rwlock_tryrdlock函数

函数原型:

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

函数作用:

非阻塞以读方式请求读写锁(非阻塞请求读锁)

pthread_rwlock_trywrlock函数

函数原型:

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

函数作用:

非阻塞以写方式请求读写锁(非阻塞请求写锁)

 
/* 3个线程不定时 "写" 全局资源,5个线程不定时 "读" 同一全局资源 */

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

int counter;                          //全局资源
pthread_rwlock_t rwlock;

void *th_write(void *arg)
{
    int t;
    int i = (int)arg;

    while (1) {
        t = counter;
        usleep(1000);

        pthread_rwlock_wrlock(&rwlock);
        printf("=======write %d: %lu: counter=%d ++counter=%d\n", i, pthread_self(), t, ++counter);
        pthread_rwlock_unlock(&rwlock);

        usleep(5000);
    }
    return NULL;
}

void *th_read(void *arg)
{
    int i = (int)arg;

    while (1) {
        pthread_rwlock_rdlock(&rwlock);
        printf("----------------------------read %d: %lu: %d\n", i, pthread_self(), counter);
        pthread_rwlock_unlock(&rwlock);

        usleep(900);
    }
    return NULL;
}

int main(void)
{
    int i;
    pthread_t tid[8];

    pthread_rwlock_init(&rwlock, NULL);

    for (i = 0; i < 3; i++)
        pthread_create(&tid[i], NULL, th_write, (void *)i);

    for (i = 0; i < 5; i++)
        pthread_create(&tid[i+3], NULL, th_read, (void *)i);

    for (i = 0; i < 8; i++)
        pthread_join(tid[i], NULL);

    pthread_rwlock_destroy(&rwlock);            //释放读写琐

    return 0;
}

更多精彩内容,请关注公众号良许Linux,公众内回复1024可免费获得5T技术资料,包括:Linux,C/C++,Python,树莓派,嵌入式,Java,人工智能,等等。公众号内回复进群,邀请您进高手如云技术交流群。

img


最后,最近很多小伙伴找我要Linux学习路线图,于是我根据自己的经验,利用业余时间熬夜肝了一个月,整理了一份电子书。无论你是面试还是自我提升,相信都会对你有帮助!

免费送给大家,只求大家金指给我点个赞!

电子书 | Linux开发学习路线图

也希望有小伙伴能加入我,把这份电子书做得更完美!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

标签:rwlock,加锁,函数,int,读写,Linux,pthread
From: https://www.cnblogs.com/xuanmiao363/p/16647419.html

相关文章

  • Linux0.11 sleep_on wake_up函数理解和纠正
    /**将当前进程设置为不可中断的睡眠状态*只有明确进程唤醒才可以*/voidsleep_on(structtask_struct**p){structtask_struct*tmp;if(!p)......
  • Linux:按一个文件的每一行查找另一个文件
     #!/usr/bin/bashforjin`ls$1/*/*_nv.tsv`#我的目标文件是以_nv.tsv结尾的,所以将他们全列出dojj=${j##*/}jjj=${jj%_*}echo$jjj>>testnv.txt......
  • Linux下软件安装的几种方式
    Linux的软件安装目录是也是有讲究的,理解这一点,在对系统管理是有益的/usr:系统级的目录,可以理解为C:/Windows//usr/lib:理解为C:/Windows/System32/usr/bin:几乎所有的系......
  • Linux centOS 7下安装配置Tomcat
    环境:我这边使用的是3A服务器的CentOS7.9系统Tomcat下载地址:https://tomcat.apache.org/download-80.cgi安装rz工具上传安装包yum-yinstalllrzsz安装tomcat创建Tom......
  • SPI协议的数据读写实现(spi_slave)
    SPI协议的数据读写实现(spi_slave)  ......
  • 各硬件设备在Linux中的文档名
    设备设备在Linux內的文档名SCSI/SATA/USB硬盘/dev/sd[a-p]U盘/dev/sd[a-p](与SATA相同)VirtI/O界面/dev/vd[a-p](用于虚拟机內)软盘机/dev/fd[0-1]......
  • [CSharpTips]C# 读写INI文件
    读写.ini文件工具可以直接使用usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Runtime.InteropServices;usingSystem.Text;names......
  • Linux: 字符串截取
    假设定义了一个变量为:代码如下: file=/dir1/dir2/dir3/my.file.txt可以用${}分别替换得到不同的值:${file#*/}:删掉第一个/及其左边的字符串:dir1/dir2/dir3/my.file.txt......
  • Linux0.11 move_to_user_mode分析
    /**IRET*当使用IRET指令返回到相同保护级别的任务时,也就是当前的CS中的DPL和堆栈中的DPL相同时*IRET会从堆栈弹出代码段选择子及指令指针分别到CS与IP寄存器,*......
  • linux统计文件个数
    统计当前目录下文件的个数(不包括目录)$ls-l|grep"^-"|wc-l统计当前目录下文件的个数(包括子目录)$ls-lR|grep"^-"|wc-l查看某目录下文件夹(目录)的个数......