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

多线程同步之读写锁

时间:2022-11-07 19:04:47浏览次数:48  
标签:rwlock 同步 attr int 读写 线程 pthread 多线程


对于多线程程序来说,同步是指在一定的时间内只允许某一个线程访问某个资源 。 而在
此时间内,不允许其他的线程访问该资源。同步资源的方式:互斥锁、条件变量、读写锁、
信号量。

读写锁:
一、基本原理
1、读写锁的 3 种状态
1)当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都
会被阻塞。(写锁,阻塞后面的其它读写锁操作)
2)当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问
权,但是以写模式对它进行加锁的线程将会被阻塞。(读锁,阻塞后面的写锁,不阻塞后面的读锁)
3)
2、读写锁机制是由 POSIX 提供的,如果写者没有持有读写锁,那么所有的读者都可
以持有这把锁,而一旦有某个写者阻塞在上锁的时候,那么就由 POSIX 系统来决定是否允许
读者获取该锁 。

二、API
1)初始化和销毁读写锁
初始化的方式:两种
a、通过给一个静态分配的读写锁赋予常量值 PTHREAD_RWLOCK_INITIALIZER 来初始化
b、动态 初始化,调用pthread_rwlock_init(),当线程不再需要读写锁的时候,通过调用

销毁pthread_rwlock_destory()
函数原型如下
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

在初始化读写锁的时候,如果attr为空,表示使用默认属性
初始化和销毁的返回值,如果执行成功返回0,出错返回错误码
//使用非默认属性
int pthread_rwlockattr_init(pthread_rwl ockattr_t *attr) ;
int pthread_rwlockattr_destroy(pthread_rwlockatttr_ t *attr);
同样如果调用成功返回0,失败返回错误码
  1. 获取和释放读写锁
    pthread_rwlock_rdlock()用来获取读出锁,如果相应的读出锁已经被某个写入者占有 ,那么就阻塞调
    用线程 。
    pthread_ rwlock_wrlock()以获取一个写入锁,如果相应 的写入锁已经被其他写人者或者
    读出者占有(一个或多个),那么就阻塞该调用线程;
    pthread_ rwlock_ unlock(),用来释放一个读出或写入锁

下面是三个函数的函数原型
int pthread_ rwlock_rdlock(pthread_ rwlock_t *rWPtr);
int pthread_ rwlock_wrlock(pthread_ rwlock_ t *rWPtr) ;
int pthread_ rwlock_unlock(pthread_ rwlock_t *rWPtr) ;
这三个函数若调用成功,则返回0,失败则返回错误码
注意的是 , 其中获取锁的两个函数的操作都是阻塞操作,也就是说获取不到锁的话,
那么调用线程不是立即返回,而是阻塞执行
下面是两个非阻塞方式获得读写锁的函数非阻塞方式下获取锁的时候,如果不能马上获取到,就会立 即返回一个 EBUSY 错误提示 ,
而不是把调用线程投入到睡眠等待,函数原型如下
int pthread_ rwlock_ tryrdlock(pthread_ rwlock_ t *rWPtr) ;
int pth read_rwlock_t.rywrlock (pthread_rwlock_t *rWPtr) ;

同样调用成功返回0,调用失败返回错误码

三、读写锁的demo

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#define THREADNUM 5
pthread_rwlock_t rwlock;
void *readers(void *arg)
{
pthread_rwlock_rdlock(&rwlock);
printf("reader %ld got the lock\n", (long)arg);
pthread_rwlock_unlock(&rwlock);
pthread_exit((void*)0);
}
void *writers(void *arg)
{
pthread_rwlock_wrlock(&rwlock);
printf("writer %ld got the lock\n", (long)arg);
pthread_rwlock_unlock(&rwlock);
pthread_exit((void*)0);
}
int main(int argc, char **argv){
int iRet, i;
pthread_t writer_id, reader_id;
pthread_attr_t attr;
int nreadercount = 1, nwritercount = 1;
iRet = pthread_rwlock_init(&rwlock, NULL);
if (iRet)
{
fprintf(stderr, "init lock failed\n");
return iRet;
}
pthread_attr_init(&attr);
/*pthread_attr_setdetachstate用来设置线程的分离状态
也就是说一个线程怎么样终止自己,状态设置为PTHREAD_CREATE_DETACHED
表示以分离状态启动线程*/
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(i = 0; i < THREADNUM; i++)
{
if (i % 3)
{
pthread_create(&reader_id, &attr, readers, &nreadercount);
printf("create reader %d\n", nreadercount++);
}
else
{
pthread_create(&writer_id, &attr, writers, &nwritercount);
printf("create writer %d\n", nwritercount++);
}
}

for(int i = 0;i < THREADNUM;i++)
{
int iRet = pthread_attr_destroy(&attr);
if(0 != iRet)
{
printf("pthread_attr_destroy error \n");
}
}
sleep(5);/*sleep是为了等待另外的线程的执行*/
return 0;
}
//运行环境Ununtu
把文件命名为Thread.cpp
编译:g++ -o Thread Thread.cpp -lpthread
运行./Thread


标签:rwlock,同步,attr,int,读写,线程,pthread,多线程
From: https://blog.51cto.com/u_11320078/5830863

相关文章

  • 多线程同步之信号量
    对于多线程程序来说,同步是指在一定的时间内只允许某一个线程访问某个资源。而在此时间内,不允许其他的线程访问该资源。同步资源的方式:互斥锁、条件变量、读写锁、信号......
  • C# 多线程访问之 SemaphoreSlim(信号量)【C# 进阶】
    SemaphoreSlim是对可同时访问某一共享资源或资源池的线程数加以限制的Semaphore的轻量替代,也可在等待时间预计很短的情况下用于在单个进程内等待。由于SemaphoreSlim......
  • E710八通道读写器7189 Lite
    简介   E710八通道超高频电子标签读写器是一款高性能的UHF超高频电子标签读写器,完全自主知识产权设计,结合专有的高效信号处理算法,在保持高识读率的同时,实现对电子标签的......
  • 用Rust实现一个多线程的web server
    在本文之前,我们用Rust实现一个单线程的webserver的例子,但是单线程的webserver不够高效,所以本篇文章就来实现一个多线程的例子。单线程webserver存在的问题请求只能串行处......
  • java多线程生产者消费者线程并发协作测试心得
    图11-17生产者消费者示意图产品classChicken{intid;publicChicken(intid){this.id=id;}}缓冲区(装产品)classContainer{//定......
  • 多线程
    JUC并发编程多线程三种创建方式继承Thread(Thread实现了Runnable接口)实现Runnable(这种方式需要将该实现类作为参数调用Thread对象)实现Callable线程的状态线程方法......
  • 多线程
    1、程序、进程、线程程序(program)是为了完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象进程(process)是程序的一次执行过程,或是正在运行的一......
  • CPU端多进程/多线程调用CUDA是否可以加速???
    相关:NVIDIA显卡cuda的多进程服务——MPS(Multi-ProcessService)tensorflow1.x——如何在C++多线程中调用同一个session会话tensorflow1.x——如何在python多线程中......
  • 多线程的异常处理
    1.异常在线程内部处理多线程使用过程中,在线程内部使用try...catch...是可以捕获异常的。但是外部使用try...catch...通常无法捕获异常,也就是说程序不会throw异常(异常被吞......
  • 线程同步-读者写者问题(多线程)
    问题描述    有读者和写者两个并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数......