Duangw

读写锁

索引:

  1. 初始化一个读写锁pthread_rwlock_init
  2. 读锁定读写锁pthread_rwlock_rdlock
  3. 非阻塞读锁定pthread_rwlock_tryrdlock
  4. 写锁定读写锁pthread_rwlock_wrlock
  5. 非阻塞写锁定pthread_rwlock_trywrlock
  6. 解锁读写锁pthread_rwlock_unlock
  7. 释放读写锁pthread_rwlock_destroy

1.初始化一个读写锁pthread_rwlock_init

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwlock, \
	const pthread_rwlockattr_t *attr);
返回值:函数成功返回0;任何其他返回值都表示错误

初始化rwlock指定的读写锁,它的属性被参数attr指定。如果attr的值为NULL,初始化读写锁时使用缺省的读写锁属性。其效果和attr指向一个缺省的读写锁属性对象是一样的。

成功初始化后,读写锁的状态为非锁定的。

对一个已经初始化过的读写锁调用pthread_rwlock_init函数会产生不可预测的后果。使用一个未经初始化的读写锁也会产生不可预测的后果。

如果需要缺省属性的读写锁,可以用宏PTHREAD_RWLOCK_INITIALIZER初始化静态的读写锁变量。但是,静态初始化读写锁不进行错误检查。如:

pthread_rwlock_t rwlock = PTHREASD_RWLOCK_INITIALIZER;

 

2.读锁定读写锁pthread_rwlock_rdlock

#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

函数在rwlock读写锁上进行读锁定。

如果一个线程写锁定了读写锁,调用pthread_rwlock_rdlock函数的线程将无法读锁定读写锁,并将被阻塞,直到线程可以读锁定这个读写锁为止。

如果一个线程写锁定了读写锁后又调用pthread_rwlock_rdlock函数来读锁定同一个读写锁,结果将无法预测。

标准中没有指定当没有线程写锁定这个读写锁,但有线程试图写锁定而被阻塞在这个读写锁上时,当前线程是否能读锁定读写锁。大多数线程库往往优先考虑激活试图写锁定而被阻塞的线程,这样做是为了防止试图写锁定而被阻塞的线程长时间得不到调度。

一个线程可能对一个读写锁进行了多次读锁定(即成功调用了pthread_rwlock_rdlock()函数多次)。如果是这样的,线程必须调用pthread_rwlock_unlock()函数对读写锁进行同样次数的解锁。

当一个读写锁被读锁定了,而一个线程阻塞在这个读写锁上时,如果这时来了一个信号,那么当线程从信号处理程序中返回时,将继续阻塞在这个读写锁上。就好象线程没有被中断过。

 

3.非阻塞读锁定pthread_rwlock_tryrdlock

#include <pthread.h>
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

pthread_rwlock_tryrdlock()函数和pthread_rwlock_rdlock函数的功能相近,不同的是,当已有线程写锁定读写锁,或是有试图写锁定的线程被阻塞时,pthread_rwlock_tryrdlock函数失败返回。

 

4.写锁定读写锁pthread_rwlock_wrlock

#include <pthread.h>
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

写锁定读写锁rwlock。如果没有线程读或写锁定读写锁rwlock,当前线程将写锁定读写锁rwlock。否则线程将被阻塞,直到没有线程锁定这个读写锁为止。

如果调用这个函数之前,本线程已经读或写锁定了这个读写锁,那么pthread_rwlock_wrlock函数运行的结果是不可预测的。

读写锁被解开以后,激活阻塞在读写锁上的线程时,往往优先考虑试图写锁定而被阻塞的线程,这样做是为了防止试图写锁定而被阻塞的线程长时间得不到调度。

当一个读写锁被写锁定了,而一个线程阻塞在这个读写锁上时,如果这时来了一个信号,那么当线程从信号处理程序中返回时,将继续阻塞在这个读写锁上。就好像线程没有被中断过。

 

5.非阻塞写锁定pthread_rwlock_trywrlock

#include <pthread.h>
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

pthread_rwlock_trywrlock函数的功能和pthread_rwlock_wrlock函数相近。不同的是如果有其他线程锁定了读写锁,pthread_rwlock_trywrlock函数会失败返回。

 

6.解锁读写锁pthread_rwlock_unlock

#include <pthread.h>
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

解锁一个读写锁。

调用pthread_rwlock_unlock函数之前必须调用pthread_rwlock_rdlock函数或pthread_rwlock_wrlock函数锁定读写锁。否则结果是不可预测的。

在pthread_rwlock_unlock函数被用来解锁对读写锁的读锁定后,如果本线程对这个读写锁还有其他读锁定,那么这个读写锁对本线程将继续保持读锁定状态。如果pthread_rwlock_unlock函数解开了当前线程在这个读写锁上的最后一个读锁定,那么当前线程将不再拥有对这个读写锁的读锁定。如果pthread_rwlock_unlock函数解开了这个读写锁上的最后一个锁定,那么这个读写锁将处在非锁定状态。

如果pthread_rwlock_unlock函数被用来解锁对读写锁的写锁定,那么函数返回后,这个读写锁将处在非锁定状态。

如果用pthread_rwlock_unlock函数解锁一个读写锁时,有多个线程在等待对这个读写锁进行写锁定,系统将用调度策略决定激活哪个线程对读写锁进行写锁定。

如果用pthread_rwlock_unlock函数解锁一个读写锁时,有多个线程在等待对这个读写锁进行读锁定,系统将用调度策略决定按什么顺序激活各个线程对读写锁进行读锁定。

如果用pthread_rwlock_unlock函数解锁一个读写锁时,有多个线程在等待对这个读写锁进行写锁定和读锁定,一般先激活需要写锁定的线程对读写锁进行写锁定(标准没有指定在这种情况下应该先激活写线程还是先激活读线程)。

 

7.释放读写锁pthread_rwlock_destroy

#include <pthread.h>
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
返回值:函数成功返回0;任何其他返回值都表示错误

释放读写锁rwlock,并释放这个读写锁占用的资源。一般情况下,pthread_rwlock_destroy函数将rwlock指向的互斥锁对象设置为非法值。

释放了一个读写锁之后,在pthread_rwlock_init重新初始化它之前,再使用这个读写锁会有不可预料的结果。

如果有线程锁定了某个读写锁,那么用pthread_rwlock_destroy()函数释放这个读写锁会引起不可预知的结果。

试图释放一个未初始化的读写锁会引起不可预知的结果。