读写锁的实现原理(pthread_rwlock_t)
引言
不同的锁之间的语义是不一样的,没有一劳永逸的锁,只有更适合的锁。
如果是同一进程里的不同线程共享读写锁,那么读写锁变量的维护是在进程内部即可。如果是不同进程共享读写锁,那么读写锁变量的维护是在共享存储区。
读写锁的分配规则:
(1)只要没有线程占用写锁,那么任意数目的线程都可以持有这个读锁。
(2)只要没有线程占用读写锁,那么才能为一个线程分配写锁。
读锁相当于一个共享锁,写锁i相当于独占锁。
和当初上操作系统讲的读者写者问题一样,只是当初好不理解啊。
读写锁实现原理
一种实现机制——互斥锁和条件变量。读者有兴趣可以自己实现一种。这种实现是一种写优先。
1、pthread_rwlock_t数据结构
typedef struct{
pthread_mutex_t rw_mutex;// basic lock on this struct
pthread_cond_t rw_condreaders;//for reader
pthread_cond_t rw_condwriteres;//for writer
int rw_magic; //for error checking
int rw_nwaiterreaders; //the num of readers
int rw_nwaiterwirteres; //the num of writers
int rw_refcount; //-1 is writer has this lock else reader has this lock
}pthread_rwlock_t;
rw_magic这个成员,如果没有设置属性的时候,创建锁的时候就会给予一个默认值(用于检查传递的锁是否是一个已经完成初始化的锁)。摧毁锁的时候,设置为0.
rw_refcount这个成员,它是用来指示本读写锁的当前状态,-1表示写锁,0表示可用,>0则意味着有多个读进程占用该锁。
申请一个读锁时,
锁的释放,假定优先唤醒写操作:


2、同一进程里面的不同线程,是可以相互取消的。相互取消这种情况还是会发生的,比如一个线程发现了一些错误,这些错误是致命的,所以要通知其他线程,你们别干了,再干下去还是会遇到错误,所以就把他们取消了。拿本设计结构来说,如果被取消的线程是获取了互斥锁,并且阻塞在pthread_cond_wait调用中,这个时候应该怎们办呢?因为,线程被动终止(可能没有解互斥锁的调用),而不是主动中止(有解互斥锁的调用),用到清理程序。清理程序会在线程终止时被调用,无需主动显式调用。
pthread_cleanup_push(void (*func(void *)),void *arg);
pthread_cleanup_pop(int excute);显式取消所注册的清理程序
读写锁的实现原理(pthread_rwlock_t)的更多相关文章
- Java 读写锁 ReadWriteLock 原理与应用场景详解
Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理@mikechen 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Loc ...
- Linux读写锁的使用
读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排它的,读可以有多个在读,写只有唯一个在写,写的时候不允许读. 具有强读者同步和强写者同步两种形式: 强读者同步:当写者没有进行写操作时,读者就 ...
- c++ 读写锁
#ifndef THREAD_UTIL_H #define THREAD_UTIL_H #include <pthread.h> namespace spider { class Auto ...
- 【C/C++多线程编程之九】pthread读写锁
多线程编程之读写锁 Pthread是 POSIX threads 的简称,是POSIX的线程标准. pthread读写锁把对共享资源的訪问者分为读者和写者,读者仅仅对共享资源 ...
- Linux环境编程之同步(三):读写锁
概述 相互排斥锁把试图进入我们称之为临界区的全部其它线程都堵塞住.该临界区通常涉及对由这些线程共享一个或多个数据的訪问或更新.读写锁在获取读写锁用于读某个数据和获取读写锁用于写直接作差别. 读写锁的分 ...
- 读写锁(read-write lock)机制-----多线程同步问题的解决
原文: http://blog.chinaunix.net/uid-27177626-id-3791049.html ----------------------------------------- ...
- pthread_rwlock pthread读写锁
原文: http://www.cnblogs.com/diegodu/p/3890450.html 使用读写锁 配置读写锁的属性之后,即可初始化读写锁.以下函数用于初始化或销毁读写锁.锁定或解除锁定读 ...
- java并发锁ReentrantReadWriteLock读写锁源码分析
1.ReentrantReadWriterLock 基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读 ...
- linux使用读写锁pthread_rwlock_t
转自:http://blog.csdn.net/onlyou930/article/details/6755593 使用读写锁 配置读写锁的属性之后,即可初始化读写锁.以下函数用于初始化或销毁读写锁. ...
随机推荐
- linux下制作u盘启动盘
格式化u盘为fat32 fdisk -l #查看U盘盘符,或者 df -T umount /dev/sdb #先卸载u盘 mkfs.vfat /dev/sdb #格式化为fat32模式,或者 mkfs ...
- Educational Codeforces Round 15_D. Road to Post Office
D. Road to Post Office time limit per test 1 second memory limit per test 256 megabytes input standa ...
- ntity Framework技巧系列之四 - Tip 13 – 15
提示13. 附加一个实体的简单方式 问题: 在早先的一些提示中,我们讨论了使用Attach来加载一个处于未改变(unchanged)状态的东西到ObjectContext从而避免进行查询的开销. 如果 ...
- golang vs java
http://programmers.stackexchange.com/questions/83780/how-fast-can-go-go In terms of language design, ...
- PCI源码学习笔记
这个是PCI的关键结构体. static const struct file_operations proc_bus_pci_operations = { .owner = THIS_MODULE, ...
- C#中使用正则表达式提取超链接地址的集中方法
一般在做爬虫或者CMS的时候经常需要提取 href链接或者是src地址.此时可以使用正则表达式轻松完成. Regex reg = new Regex(@"(?is)<a[^>]* ...
- MySQL与Oracle的区别
1.语法上的区别 变量类型定义.IN OUT的位置.变量定义的位置.游标的位置.异常的位置: 2.MySQL没有 return 关键字,采用leave label的方式结束循环或跳出存储 3.异常处 ...
- 源码篇:SDWebImage
攀登,一步一个脚印,方能知其乐 源码篇:SDWebImage 源码来源:https://github.com/rs/SDWebImage 版本: 3.7 SDWebImage是一个开源的第三方库,它提 ...
- auto ash v1
startdate=$1enddate=$2#reporttype=$3#reportformat='text'oraclehome=`echo $ORACLE_HOME` dbid=`sqlplus ...
- GDT、GDTR、LDT、LDTR的理解
GDT是全局描述附表,主要存放操作系统和各任务公用的描述符,如公用的数据和代码段描述符.各任务的TSS描述符和LDT描述符.(TSS是任务状态段,存放各个任务私有运行状态信息描述符)LDT是局部描述符 ...