读写锁的分配规则:
1、只要没有线程持有某个给定的读写锁用于写,那么任意数目的线程可以持有读写锁用于读
2、仅当没有线程持有某个给定的读写锁用于读或用于写时,才能分配该读写锁用于写
这种对于某个给定资源的共享访问也称为共享-独占上锁,获取一个读写锁用于读称为共享锁,获取一个读写锁用于写称为独占锁
获取与释放读写锁
读写锁的数据类型为pthread_rwlock_t,如果这个类型的某个变量是静态分配的,那么可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化它
pthread_rwlock_rdlock获取一个读出锁,如果对应的读写锁已由某个写入者持有,那就阻塞调用线程。
pthread_rwlock_wrlock获取一个写入锁,如果对应的读写锁已由另一个写入者或一个或多个读出者持有,那就阻塞调用线程。
pthread_rwlock_unlock释放一个读出锁或写入锁
#include <pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_unlock(pthread_rwlock_t *rwptr);
成功返回0,出错时为正的Exxx值
下面两个函数尝试获取一个读出锁或写入锁,但是如果该锁不能马上取得,那就返回一个EBUSY错误,而不是把 调用线程投入睡眠
#include <pthread.h>
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
成功返回 0,出错返回为正的Exxx值
读写锁属性
静态分配的读写锁可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化。读写锁变量也可以通过调用pthread_rwlock_init动态的初始化。当一个线程不再需要某个读写锁时,它可以调用pthread_rwlock_destroy销毁
#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwptr, pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);
成功返回 0,失败返回为正的Exxx值
初始化某个读写锁时,如果attr是个空指针,那就使用缺省属性。要赋予它非缺省的属性,需使用下列两个函数
#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
成功返回 0,失败返回为正的Exxx值
数据类型为pthread_rwlockattr_t的某个属性对象一旦初始化,使能或禁止特定属性就通过调用 不同的函数来完成。当前定义了的唯一属性是PTHREAD_PROCESS_SHARED,它指定相应的读写锁将在不同进程间共享,而不仅仅是在单个进程内的不两只线程间共享。
#include <pthread.h>
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int phread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int value);
成功返回 0,出错返回为正的Exxx值
第一个函数在由valptr指向的整数中返回该属性的当前值。第二个函数把该属性的当前值设置为value,其值或为PTHREAD_PROCESS_PRIVATE或为PTHREAD_PROCESS_SHARED
线程取消
#include <pthread.h>
int pthread_cancel(pthread_t tid);
成功返回0,失败返回为正的Exxx值
适用情况:如果启动了多个线程以执行某个给定任务,那么首先完成任务的线程可使用线程取消功能取消其它线程。另一个例子是,当多个线程开始执行同一个任务时,如果其中一个线程发现一个错误,它和其它线程诮必要终止。
为处理被取消的可能情况,任何线程可以压入和弹出清理处理程序
#include <pthread.h>
void pthread_cleanup_push(void (*function)(void *), void *arg);
void pthread_cleanup_pop(int execute);
处理程序在以下情况时被调用:
1、调用线程被取消(由某个线程调用 pthread_cancel完成)
2、调用线程自愿终止(调用pthread_exit,或从自己的线程起始函数返回)