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();
}


代码实现效果:

相关文章
|
1天前
|
Linux 数据库
Linux内核中的锁机制:保障并发操作的数据一致性####
【10月更文挑战第29天】 在多线程编程中,确保数据一致性和防止竞争条件是至关重要的。本文将深入探讨Linux操作系统中实现的几种关键锁机制,包括自旋锁、互斥锁和读写锁等。通过分析这些锁的设计原理和使用场景,帮助读者理解如何在实际应用中选择合适的锁机制以优化系统性能和稳定性。 ####
14 6
|
7天前
|
Ubuntu Linux Shell
Linux 系统中的代码类型或脚本类型内容
在 Linux 系统中,代码类型多样,包括 Shell 脚本、配置文件、网络配置、命令行工具和 Cron 定时任务。这些代码类型广泛应用于系统管理、自动化操作、网络配置和定期任务,掌握它们能显著提高系统管理和开发的效率。
|
1月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
172 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
26天前
|
Java 应用服务中间件 测试技术
Java21虚拟线程:我的锁去哪儿了?
【10月更文挑战第8天】
30 0
|
1月前
|
安全 调度 数据安全/隐私保护
iOS线程锁
iOS线程锁
25 0
|
1月前
|
Java API
【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁
【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁
27 0
|
1月前
|
安全 Java 程序员
【多线程-从零开始-肆】线程安全、加锁和死锁
【多线程-从零开始-肆】线程安全、加锁和死锁
41 0
|
1月前
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
17天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
122 5
|
17天前
|
Linux
Linux系统之expr命令的基本使用
【10月更文挑战第18天】Linux系统之expr命令的基本使用
55 4