首页 > 其他分享 >线程同步 读写锁

线程同步 读写锁

时间:2023-08-30 14:11:23浏览次数:31  
标签:rwlock 同步 int 读写 读锁 线程 pthread

目录

读写锁

一把锁,并不是读锁和写锁
称之为读写锁,因为他既可以锁定读操作,也可以锁定写操作

pthread_rwlock_t rwlock;

锁中记录了

  • 锁的状态 打开关闭
  • 锁定的操作 锁读 锁写
  • 哪个线程持有钥匙

使用方式和互斥锁相同:

  1. 找共享资源
  2. 确定临界区
  3. 临界区加锁,解锁

特点

  1. 读锁锁定了临界区,线程对临界区的访问是并行的,读锁共享
  2. 写锁锁定了临界区,线程对临界区的访问是串行的,写锁独占
  3. 多个请求读写锁,写锁优先

读操作多时,可以选用读写锁,效率较高

函数

初始化和析构

#include<pthread_h>
pthread_rwlock_t rwlock;
//初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
     const pthread_rwlockattr_t *restrict attr);
//释放资源
pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

rwlock 读写锁的地址,传出参数

读锁

//加读锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

调用这个函数,如果读写锁是打开的,那么加锁成功;如果读写锁已经锁定了读操作,调用这个函数依然可以加锁成功,因为读锁是共享的;
如果读写锁已经锁定了写操作,调用这个函数的线程会被阻塞

// 这个函数可以有效的避免死锁
// 如果加读锁失败, 不会阻塞当前线程, 直接返回错误号
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

写锁

// 在程序中对读写锁加写锁, 锁定的是写操作
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

如果读写锁是没上锁的,那么加锁成功。如果读写锁已经锁定,那么阻塞操作

同样有try加锁的命令

// 这个函数可以有效的避免死锁
// 如果加写锁失败, 不会阻塞当前线程, 直接返回错误号
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

解锁

//读写锁都可以解锁
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock);

读写锁使用

写一个程序,有5个线程对全局变量进行读操作,3个线程进行写操作

#include <pthread.h>
#include <iostream>
#include <bits/stdc++.h>
#include <unistd.h>
#define MAX 50
// 全局变量
int number;

pthread_rwlock_t rwlock1;

using namespace std;

void *read_num(void *arg)
{
    for (int i = 0; i < MAX; i++)
    {
        pthread_rwlock_rdlock(&rwlock1);
        cout << "thread read,id= " << pthread_self() << " number= " << number << endl;
        pthread_rwlock_unlock(&rwlock1);
        usleep(rand() % 5);
    }
    return NULL;
}
void *write_num(void *arg)
{
    for (int i = 0; i < MAX; i++)
    {
        pthread_rwlock_wrlock(&rwlock1);
        int cur=number;
        cur++;
        number=cur;
        cout << "thread write,id= " << pthread_self() << " number= " << number << endl;
        pthread_rwlock_unlock(&rwlock1);
    };
    return NULL;
}

int main()
{
    pthread_t p1[5], p2[3];
    // 初始化锁
    pthread_rwlock_init(&rwlock1, NULL);

    // 5个读线程,3个写线程
    for (int i = 0; i < 5; i++)
    {
        pthread_create(&p1[i], NULL, read_num, NULL);
    }
    for (int i = 0; i < 3; i++)
    {
        pthread_create(&p1[i], NULL, write_num, NULL);
    }

    // 阻塞后资源回收
    for (int i = 0; i < 5; i++)
    {
        pthread_join(p1[i], NULL);
    }
    for (int i = 0; i < 3; i++)
    {
        pthread_join(p2[i], NULL);
    }
    // 释放锁
    pthread_rwlock_destroy(&rwlock1);
    return 0;
}

实现结果

标签:rwlock,同步,int,读写,读锁,线程,pthread
From: https://www.cnblogs.com/liviayu/p/17667054.html

相关文章

  • 线程篇--线程的特点
    1.线程是轻量级进程(light-weightprocess),也有PCB,创建线程使⽤的底层函数和进程⼀样,都是clone;2.从内核⾥看进程和线程是⼀样的,都有各⾃不同的PCB;3.进程可以蜕变成线程;4.在linux下,线程最是⼩的执⾏单位;进程是最⼩的分配资源单位。实际上,⽆论是创建进程的fork,还是创建线......
  • 线程同步 死锁
    目录加锁后忘记解锁重复加锁,造成死锁死锁成环如何避免加锁后忘记解锁//场景1voidfunc(){for(inti=0;i<6;++i){//当前线程A加锁成功,当前循环完毕没有解锁,在下一轮循环的时候自己被阻塞了//其余的线程也被阻塞 pthread_mutex_lock(......
  • 初识MQ-同步通讯的优缺点
       ......
  • python多线程
    python多线程多线程threading,利用CPU和IO可以同时执行的原理多进程multiprocessing,利用多核CPU的能力,真正的并行执行任务异步IOasyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行使用Lock对资源加锁,防止冲突访问使用Queue实现不同线程/进程之间的数据通信,实现生......
  • leetcode & c++多线程刷题日志
    1.按序打印按序打印解法互斥锁classFoo{mutexmtx1,mtx2;public:Foo(){mtx1.lock(),mtx2.lock();}voidfirst(function<void()>printFirst){printFirst();mtx1.unlock();}voidsecond(function<voi......
  • 多线程|volatile的使用
    一、内存可见性问题先来看如下代码classMyCounter{publicintflag=0;}publicclassThreadDemo22{publicstaticvoidmain(String[]args){MyCountermyCounter=newMyCounter();Threadt1=newThread(()->{while(myCounter.f......
  • DataX数据同步- 不同时间Where条件
    DataX数据同步工具一、介绍:DataX是用来数据同步得第三方工具,能够进行分片,高效得数据同步二、时间自增,根据时间进行数据同步:1.相关截图:  2.where条件处理:主要分为三个数据库的数据同步,不同的处理1.postgresqlreader:ic_shopee_shopperformance"where":"customer_id......
  • 16、Flink 的table api与sql之连接外部系统_ 读写外部系统的连接器和格式以及Apache H
    (文章目录)本文介绍了ApacheHive连接器的使用,以具体的示例演示了通过java和flinksqlcli创建catalog。本文依赖环境是hadoop、zookeeper、hive、flink环境好用,本文内容以flink1.17版本进行介绍的,具体示例是在1.13版本中运行的(因为hadoop集群环境是基于jdk8的,flink1.17版本需......
  • nginx同步脚本
    检测nginx进程是否存在异常`#!/bin/bash收集nginx进程pidpid=$(ps-ef|grepnginx|grepworker|awk'{print$2}')收集第一个nginx进程的pid,打上时间戳pid0=$(ps-ef|grepnginx|grepworker|awk'{print$2}'|head-n1)starttime0=$(ps-olstart=-p$pid0)startti......
  • 这是一个基于threading可停止线程的有限容量有限并行度的python任务管理器
    这是一个可停止线程的有限容量有限并行度的任务管理器基于:GitHub-AlitaIcon/StopableThreadJob:可停止线程任务管理器QuickStart基础调用与效果importtimeimportdatetimefromloguruimportloggerfromStopableThreadJob.job_managerimportJobManagerif__name......