什么是读写锁:
读写锁实际是种特殊的旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进读访问,写者则需要对共享资源进写操作。这种锁相对于旋锁,能提并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最可能的读者数为实际的逻辑CPU数。写者是排他性的个读写锁同时只能有个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
相关函数为:
1.初始化和销毁读写锁
对于读写锁变量的初始化可以有两种方式,一种是通过给一个静态分配的读写锁赋予常值PTHREAD_RWLOCK_INITIALIZER来初始化它,另 一种方法就是通过调用pthread_rwlock_init()来动态的初始化。而当某个线程不再需要读写锁的时候,可以通过调用 pthread_rwlock_destroy来销毁该锁。函数原型如下:
这两个函数如果执行成功均返回0,如果出错则返回错误码。
在释放某个读写锁占用的内存之前,要先通过pthread_rwlock_destroy对读写锁进行清理,释放由pthread_rwlock_init所分配的资源。
在初始化某个读写锁的时候,如果属性指针attr是个空指针的话,表示默认的属性;如果想要使用非默认属性,则要使用到下面的两个函数:
#include
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockatttr_t *attr);
这两个函数同样的,如果执行成功返回0,失败返回错误码。
这里还需要说明的是,当初始化读写锁完毕以后呢,该锁就处于一个非锁定状态。
数据类型为pthread_rwlockattr_t的某个属性对象一旦初始化了,就可以通过不同的函数调用来启用或者是禁用某个特定的属性。
2.获取和释放读写锁
读写锁的数据类型是pthread_rwlock_t,如果这个数据类型中的某个变量是静态分配的,那么可以通过给它赋予常值 PTHREAD_RWLOCK_INITIALIZAR来初始化它。pthread_rwlock_rdlock()用来获取读出锁,如果相应的读出锁已 经被某个写入者占有,那么就阻塞调用线程。pthread_rwlock_wrlock()用来获取一个写入锁,如果相应的写入锁已经被其它写入者或者一 个或多个读出者占有,那么就阻塞该调用线程;pthread_rwlock_unlock()用来释放一个读出或者写入锁。函数原型如下:
这三个函数若调用成功则返回0,失败就返回错误码。要注意的是其中获取锁的两个函数的操作都是阻塞操作,也就是说获取不到锁的话,那么调用线程不是立即返 回,而是阻塞执行。有写情况下,这种阻塞式的获取所得方式可能不是很适用,所以,接下来引入两个采用非阻塞方式获取读写锁的函数 pthread_rwlock_tryrdlock()和pthread_rwlock_trywrlock(),非阻塞方式下获取锁的时候,如果不能马 上获取到,就会立即返回一个EBUSY错误,而不是把调用线程投入到睡眠等待。函数原型如下:
#include
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
同样地,这两个函数调用成功返回0,失败返回错误码。
下面举一个关于读写锁的小例子:
相关代码:
#include<stdio.h> #include<pthread.h> pthread_rwlock_t rwlock; int buf; void *reader(void *arg) { while(1) { pthread_rwlock_rdlock(&rwlock); printf("reader is reading:%d\n",buf); pthread_rwlock_unlock(&rwlock); sleep(1); } } void *writer(void *arg) { int i=0; while(1) { pthread_rwlock_wrlock(&rwlock); buf =i++; printf("writer:%d\n",buf); pthread_rwlock_unlock(&rwlock); sleep(1); } } int main() { pthread_t tid1,tid2,tid3; pthread_create(&tid1,NULL,writer,NULL); pthread_create(&tid2,NULL,reader,NULL); pthread_create(&tid3,NULL,reader,NULL); pthread_rwlock_init(&rwlock,NULL); pthread_join(tid1,NULL); pthread_join(tid2,NULL); pthread_join(tid3,NULL); return 0; }
运行结果如下: