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

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

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

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

三种关系:

    读者与读者:无关系

    写者与写者:互斥

    读者与写者:同步与互斥

两类人:读者,写者

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

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

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

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

读写锁比起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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值