读写锁解决读者与写者问题
2017-04-12 12:50
197 查看
读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。
在编写多线程的时候,有一种情况是比较常见的。那就是,有些公共数据修改的机会比较少。相较改写,它们读的机会反而多的多。
读者写者模式:三种关系,两类人,一个场所
三种关系:
读者与读者:无关系
写者与写者:互斥
读者与写者:同步与互斥
两类人:读者,写者
一个场所:同一临界资源(数据)
自旋锁:如果所等待条件不满足,不挂起,一直申请锁。适宜某个线程占用锁时间较短。读写锁就是一种自旋锁,在用户看来表现的是阻塞式等待,但是操作系统采用的是轮询等待,直到申请到锁,互斥锁在用户看来表现的也是阻塞式等待,但是操作系统采用的是挂起等待,直到申请锁。
当不断有多个读者准备读时,如果有写者到来,此时应该让当前读者读完后,提高写者优先级,下个进入临界区的是写者。---------写者优先,否则会造成写者饥饿
当不断有多个写者准备写时,如果有读者到来,此时应该让当前写者写完后,提高读者优先级,下个进入临界区的是读者。---------读者优先,否则会造成读者饥饿
读写锁比起mutex具有更高的适用性,具有更高的并行性,可以有多个线程同时占用读模式的读写锁,但是只能有一个线程占用写模式的读写锁,读写锁的三种状态:
1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞
2.当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行加锁的线程将会被阻塞
3.当读写锁在读模式的锁状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁的请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求则长期阻塞。
读写锁最适用于对数据结构的读操作次数多于写操作的场合,因为,读模式锁定时可以共享,而写模式锁定时只能某个线程独占资源,因而,读写锁也可以叫做个共享-独占锁。
读写锁的操作:
头文件:#include<pthread.h>
读写锁的初始化:
定义读写锁: pthread_rwlock_t m_rw_lock;
函数原型: pthread_rwlock_init(pthread_rwlock_t * ,pthread_rwattr_t *);
返回值:0,表示成功,非0为一错误码,函数第二个参数一般是NULL,采用系统默认的属性
读写锁的销毁:
函数原型: pthread_rwlock_destroy(pthread_rwlock_t* );
返回值:0,表示成功,非0表示错误码
获取读写锁的读锁操作:分为阻塞式获取和非阻塞式获取,如果读写锁由一个写者持有,则读线程会阻塞直至写入者释放读写锁。(读者优先)
阻塞式:
函数原型:pthread_rwlock_rdlock(pthread_rwlock_t*);
非阻塞式:
函数原型:pthread_rwlock_tryrdlock(pthread_rwlock_t*);
返回值: 0,表示成功,非0表示错误码,非阻塞会返回ebusy而不会让线程等待
获取读写锁的写锁操作:分为阻塞和非阻塞,如果对应的读写锁被其它写者持有,或者读写锁被读者持有,该线程都会阻塞等待。(写者优先)
阻塞式:
函数原型:pthread_rwlock_wrlock(pthread_rwlock_t*);
非阻塞式:
函数原型:pthread_rwlock_trywrlock(pthread_rwlock_t*);
返回值: 0,表示成功
释放读写锁:
函数原型:pthread_rwlock_unlock(pthread_rwlock_t*);
注意:读锁和写锁最后都采用同一个释放锁的函数
在编写多线程的时候,有一种情况是比较常见的。那就是,有些公共数据修改的机会比较少。相较改写,它们读的机会反而多的多。
读者写者模式:三种关系,两类人,一个场所
三种关系:
读者与读者:无关系
写者与写者:互斥
读者与写者:同步与互斥
两类人:读者,写者
一个场所:同一临界资源(数据)
自旋锁:如果所等待条件不满足,不挂起,一直申请锁。适宜某个线程占用锁时间较短。读写锁就是一种自旋锁,在用户看来表现的是阻塞式等待,但是操作系统采用的是轮询等待,直到申请到锁,互斥锁在用户看来表现的也是阻塞式等待,但是操作系统采用的是挂起等待,直到申请锁。
当不断有多个读者准备读时,如果有写者到来,此时应该让当前读者读完后,提高写者优先级,下个进入临界区的是写者。---------写者优先,否则会造成写者饥饿
当不断有多个写者准备写时,如果有读者到来,此时应该让当前写者写完后,提高读者优先级,下个进入临界区的是读者。---------读者优先,否则会造成读者饥饿
读写锁比起mutex具有更高的适用性,具有更高的并行性,可以有多个线程同时占用读模式的读写锁,但是只能有一个线程占用写模式的读写锁,读写锁的三种状态:
1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞
2.当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行加锁的线程将会被阻塞
3.当读写锁在读模式的锁状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁的请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求则长期阻塞。
读写锁最适用于对数据结构的读操作次数多于写操作的场合,因为,读模式锁定时可以共享,而写模式锁定时只能某个线程独占资源,因而,读写锁也可以叫做个共享-独占锁。
读写锁的操作:
头文件:#include<pthread.h>
读写锁的初始化:
定义读写锁: pthread_rwlock_t m_rw_lock;
函数原型: pthread_rwlock_init(pthread_rwlock_t * ,pthread_rwattr_t *);
返回值:0,表示成功,非0为一错误码,函数第二个参数一般是NULL,采用系统默认的属性
读写锁的销毁:
函数原型: pthread_rwlock_destroy(pthread_rwlock_t* );
返回值:0,表示成功,非0表示错误码
获取读写锁的读锁操作:分为阻塞式获取和非阻塞式获取,如果读写锁由一个写者持有,则读线程会阻塞直至写入者释放读写锁。(读者优先)
阻塞式:
函数原型:pthread_rwlock_rdlock(pthread_rwlock_t*);
非阻塞式:
函数原型:pthread_rwlock_tryrdlock(pthread_rwlock_t*);
返回值: 0,表示成功,非0表示错误码,非阻塞会返回ebusy而不会让线程等待
获取读写锁的写锁操作:分为阻塞和非阻塞,如果对应的读写锁被其它写者持有,或者读写锁被读者持有,该线程都会阻塞等待。(写者优先)
阻塞式:
函数原型:pthread_rwlock_wrlock(pthread_rwlock_t*);
非阻塞式:
函数原型:pthread_rwlock_trywrlock(pthread_rwlock_t*);
返回值: 0,表示成功
释放读写锁:
函数原型:pthread_rwlock_unlock(pthread_rwlock_t*);
注意:读锁和写锁最后都采用同一个释放锁的函数
#include<stdio.h> #include<pthread.h> #include<unistd.h> int buf = 0; //buf全局变量就是临界资源。 pthread_rwlock_t rwlock; //读写锁 void *myread(void *arg) { while (1) { if( pthread_rwlock_tryrdlock(&rwlock) != 0) //申请锁失败 { printf("writer is working!\n"); printf("reader do othrer thing!\n"); continue; //继续申请锁 } else { printf("read:%d\n",buf); pthread_rwlock_unlock(&rwlock); //释放锁 } // sleep(1); } } void *mywrite(void *arg) { while(1) { if(pthread_rwlock_trywrlock(&rwlock) != 0) { printf("reader is working!\n"); printf("writer do other thing!\n"); continue; } else { buf++; pthread_rwlock_unlock(&rwlock); } sleep(1);//写者隔1秒竞争一次锁资源 } } int main() { pthread_rwlock_init(&rwlock,NULL); //第二个参数是属性 pthread_t id1,id2; pthread_create(&id1,NULL,myread,NULL); pthread_create(&id2,NULL,mywrite,NULL); pthread_join(id1,NULL); pthread_join(id2,NULL); pthread_rwlock_destroy(&rwlock); return 0; }
相关文章推荐
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
- Linux多线程实践(6) --Posix读写锁(解决读者写者问题)
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
- 使用读写锁解决读者-写者问题
- Linux多线程实践(6) --Posix读写锁解决读者写者问题
- 用信号量和读写锁解决读者写者问题
- 线程读写锁解决读者-写者问题
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 用互斥锁解决读者-写者问题
- 使用信号量解决读者写者问题--读者优先
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 用信号量解决读者写者问题
- 读者写者问题——读者优先,写者优先,公平竞争 解决方法
- 用信号量解决读者写者问题