读写锁是用来解决读者写者问题的,读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读。
读写锁最适用于对数据结构的读操作次数多于写操作的场合,因为,读模式锁定时可以共享,而写模式锁定时只能某个线程独占资源,因而,读写锁也可以叫做个共享-独占锁。
读写锁的操作:
头文件:#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;
}