读写锁介绍
读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁。
- 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞;
- 当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行枷锁的线程将阻塞;
- 当读写锁在读模式锁状态时,如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求长期阻塞;
读写锁使用场景
读写锁适用对数据结构进行读的次数比写的次数多的情况下,因为可以进行读锁共享。而互斥锁通常用于读写串行。
读写锁相关接口函数
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); //使用互斥变量之前必须初始化
参数:
rwlock:读写锁
attr:为NULL时,表示默认属性
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); //在释放他们底层的内存之前必须摧毁
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock,const struct timespec *restrict abs_timeout); int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock,const struct timespec *restrict abs_timeout); //使应用程序获取读写锁时避免永久阻塞状态。
参数:
abs_timeout:指向timespec结构,指定线程应该停止阻塞的时间。
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); //将使用实现定义的所有属性的默认值初始化读写锁属性对象attr。 //如果指定已初始化的attr属性对象,则结果未定义。 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); //销毁读写锁属性对象。
在读写锁属性对象用于初始化一个或多个读写锁之后,影响属性对象(包括破坏)的任何函数都不会影响任何先前初始化的读写锁。
返回值:
若成功,返回0
若失败,返回出错编号
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, int *restrict pshared); //从attr引用的初始化属性对象中获取进程共享属性的值。 //将attr的进程共享属性的值存储到由pshared参数引用的对象中。 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared); //在attr引用的初始化属性对象中设置进程共享属性。
参数:
进程共享属性应设置为 PTHREAD_PROCESS_SHARED ,以允许任何可访问读写锁定分配的内存的线程对读写锁操作,即使读写锁分配在内存中这是由多个进程共享的。
如果进程共享属性为 PTHREAD_PROCESS_PRIVATE ,则读写锁只能在与初始化读写锁的线程相同的进程内创建的线程进行操作;
如果不同进程的线程尝试对这样的读写锁进行操作,则行为是未定义的。进程共享属性的默认值应为 PTHREAD_PROCESS_PRIVATE 。
返回值:
若 成功 ,返回 0
若 失败 ,返回 出错编号
使用示例
//创建读写锁 pthread_rwlock_t lock; pthread_rwlock_init(&lock,NULL); int data; /** 写端线程 **/ //加写锁 pthread_rwlock_wrlock(&lock); data++; printf("==write:%lu,%d\n",pthread_self(),data); //解锁 pthread_rwlock_unlock(&lock); sleep(1); /** 读端线程 **/ //加读锁 pthread_rwlock_rdlock(&lock); printf("==read:%lu,%d\n",pthread_self(),data); pthread_rwlock_unlock(&lock); sleep(1); //释放读写锁资源 pthread_rwlock_destroy(&lock);