Linux---线程读写锁详解及代码实现

简介: Linux---线程读写锁详解及代码实现

一、读写锁原理

在实际问题中,互斥锁可以解决大部分互斥的问题,保证资源可以被独占式使用,但是有时候互斥锁可能会导致效率降低。比如:系统中有成千上万条线程对同一资源进行访问,其中绝大部分是对其进行读取,只有少部分线程需要对其进行写入,这样使用互斥锁效率就会很低,所以使用读写锁。

读锁:获取数据( read、printf、fread、fget、get、getchar、scanf),当一个线程上了读锁,其他线程可以一直上读锁。

写锁:修改数据(write、puts、fwrite、fputs、putchar)当一个线程上了写锁,后面的其他线程读、写都不能上,直到解了第一个写锁。


二、读写锁对对应的API

1、初始化读写锁

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

attr:锁的属性一般设置为NULL

返回值:成功返回0,失败返回非0

静态初始化读写锁: pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

代码段:

 pthread_rwlock_t rwl;
 int pthread_rwlock_init_ret = pthread_rwlock_init(&rwl, NULL);
   if (pthread_rwlock_init_ret != 0)
   {
       perror("pthread_rwlock_init");
       exit(-1);
   }
   else
   {
       printf("读写锁初始化成功!\n");
   }

2、读锁、写锁、销毁读写锁

读锁:int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

写锁:int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

销毁读写锁:int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

代码段:验证上了写锁后只有在解了写锁才能再上读锁

#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_rwlock_t rwl;
void *Pthread_Task(void *arg)
{
    if ((long)arg == 1)
    {
        printf("我是第%ld号线程,我要上写锁\n", (long)arg);
        int pthread_rwlock_rdlock_ret = pthread_rwlock_wrlock(&rwl);
        if (pthread_rwlock_rdlock_ret != 0)
        {
            perror("pthread_rwlock_rdlock");
            exit(-1);
        }
        else
        {
            printf("我是%ld号线程,我上写锁成功!3s之后我解写锁\n", (long)arg);
            sleep(3);
            int pthread_rwlock_unlock_ret = pthread_rwlock_unlock(&rwl);
            if(pthread_rwlock_unlock_ret != 0)
            {
                perror("pthread_rwlock_unlock");
                exit(-1);
            }
            else
            {
                printf("解写锁成功!\n");
            }
        }
    }
    if ((long)arg == 2)
    {
        printf("我是第%ld号线程,我要上读锁\n", (long)arg);
        int pthread_rwlock_rdlock_ret = pthread_rwlock_rdlock(&rwl);
        if (pthread_rwlock_rdlock_ret != 0)
        {
            perror("pthread_rwlock_rdlock");
            exit(-1);
        }
        else
        {
            printf("我是%ld号线程,我上读锁成功!\n", (long)arg);
        }
    }
    pthread_exit(NULL);
}

int main()
{
    int pthread_rwlock_init_ret = pthread_rwlock_init(&rwl, NULL);
    if (pthread_rwlock_init_ret != 0)
    {
        perror("pthread_rwlock_init");
        exit(-1);
    }
    else
    {
        printf("读写锁初始化成功!\n");
    }
    pthread_t pid1, pid2;
    pthread_create(&pid1, NULL, Pthread_Task, (void *)1);
    sleep(1);
    pthread_create(&pid2, NULL, Pthread_Task, (void *)2);
    pause();
}


代码实现效果:

相关文章
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
11月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
386 67
|
11月前
|
Linux C语言
Linux读写锁源码分析
本文分析了读写锁的实现原理与应用场景,基于glibc 2.17源码。读写锁通过读引用计数、写线程ID、条件变量等实现,支持读优先(默认)和写优先模式。读优先时,写锁可能饥饿;写优先时,读线程需等待写锁释放。详细解析了`pthread_rwlock_t`数据结构及加解锁流程,并通过实验验证:2000个读线程与1个写线程测试下,读优先导致写锁饥饿,写优先则正常抢占锁。
358 19
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
257 26
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
287 17
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
706 3
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
存储 Ubuntu Linux
【Linux】Python代码模块化
在目录下创建py文件,并进行运行任务要点:python的os和sys系统接口,文件接口
185 0
【Linux】Python代码模块化
|
6月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
765 1
二、Linux文本处理与文件操作核心命令
|
6月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
449 137

热门文章

最新文章