上一篇说了线程条件变量:http://blog.csdn.net/sayhello_world/article/details/68926011
Linux线程读写锁:
在编写多线程的时候,有一种情况是十分常见的。 那就是,有些公共数据修改的机会比较少。相比较改写,它们读的机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地降低我们程序的效率。
以为读者写者为例,读者可能会一个接一个来读,写者可能修改临界资源的次数较少。
这时就需要用到读写锁。
读写锁为自旋锁。当申请不到的时候,系统就轮循申请,这时对于用户而言为阻塞。
互斥锁以及二元信号量为挂起等待锁。申请不到就挂起等待。
需要用到的接口:
初始化:
int pthread_rwlock_init(pthread_rwlock_t*restrict rwlock , const pthread_rwlockattr_t *restrict attr);
pthread_rwlock_t *restrict rwlock:可以为一个全局变量(pthread_rwlock_t rwlock;)。
const pthread_rwlockattr_t *restrict attr:一般设置为NULL。
销毁:
int pthread_rwlock_destroy(pthread_rwlock_t*rwlock);
加锁:
读者加锁:
int pthread_rwlock_rdlock(pthread_rwlock_t*rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t*rwlock);
第一个成功返回0,如果没有返回就在自旋。在用户看来为阻塞。
第二个若申请不到就返回,在用户看来为非阻塞。
写者加锁:
int pthread_rwlock_trywrlock(pthread_rwlock_t*rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t*rwlock);
实现读者-写者模式
代码思路:
写者写数据,读者读数据,双方加读写锁防止数据不一致问题。
代码:
#include<stdio.h>
#include<pthread.h>
int buf = 0;
pthread_rwlock_t rwlock;
void *myread(void *arg)
{
while(1)
{
if(pthread_rwlock_tryrdlock(&rwlock) != 0)
{
printf("write isworking\n");
continue;
}else{
printf("%d\n",buf);
pthread_rwlock_unlock(&rwlock);
}
sleep(1);
}
}
void *mywrite(void *arg)
{
while(1)
{
if( pthread_rwlock_trywrlock(&rwlock) != 0)
{
printf("reader isworking\n");
continue;
}
else
{
buf++;
pthread_rwlock_unlock(&rwlock);
}
}
}
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;
}
那么我们为什么要给线程加锁,这就是线程安全。
线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是已经被污染的数据。