读写锁解决读者与写者问题

来源:互联网 发布:上海淘宝代运营公司 编辑:程序博客网 时间:2024/06/07 03:11

读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。

在编写多线程的时候,有一种情况是比较常见的。那就是,有些公共数据修改的机会比较少。相较改写,它们读的机会反而多的多。

读者写者模式:三种关系,两类人,一个场所

三种关系:

    读者与读者:无关系

    写者与写者:互斥

    读者与写者:同步与互斥

两类人:读者,写者

一个场所:同一临界资源(数据)

自旋锁:如果所等待条件不满足,不挂起,一直申请锁。适宜某个线程占用锁时间较短。读写锁就是一种自旋锁,在用户看来表现的是阻塞式等待,但是操作系统采用的是轮询等待,直到申请到锁,互斥锁在用户看来表现的也是阻塞式等待,但是操作系统采用的是挂起等待,直到申请锁。

当不断有多个读者准备读时,如果有写者到来,此时应该让当前读者读完后,提高写者优先级,下个进入临界区的是写者。---------写者优先,否则会造成写者饥饿

当不断有多个写者准备写时,如果有读者到来,此时应该让当前写者写完后,提高读者优先级,下个进入临界区的是读者。---------读者优先,否则会造成读者饥饿

读写锁比起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;}





0 0
原创粉丝点击