概述

相互排斥锁把试图进入我们称之为临界区的全部其它线程都堵塞住。该临界区通常涉及对由这些线程共享一个或多个数据的訪问或更新。读写锁在获取读写锁用于读某个数据和获取读写锁用于写直接作差别。

读写锁的分配规则例如以下:

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,出错返回正值

读写锁属性
给静态分配的读写锁赋值PTHREAD_RWLOCK_INITIALIZER来初始化它。

读写锁变量也可通过调用pthread_rwlock_init来动态地初始化。

当当一个线程不再须要某个读写锁时。可调用pthread_rwlock_destroy摧毁它。

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr); //成功为0,出错为正值

初始化某个读写锁时,假设attr是空指针。就使用默认属性。

要赋予它非默认的属性,须要使用例如以下两个函数:

#include <pthread.h>
int pthread_rwlockattr_init(pthread_rwlockattr_t *rwptr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwptr); //成功为0,出错为正值

数据类型为pthread_rwlockattr_t的某个属性对象一旦初始化。就通过调用不同的函数来启用或禁止特定属性。

当前定义了的唯一属性是PTHREAD_PROCESS_SHARED,它指定相应的读写锁将不同进程间共享,而不仅仅是在单个进程内的不同线程间共享。以下两个函数分别获取和设置这个属性。

#include <pthread.h>
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int pthread_rwlockattr_setpshared(const pthread_rwlockattr_t *attr, int value); //成功返回0,出错返回正值

读写锁的实现可參考《UNP2》P142

最新文章

  1. salt源码安装软件和yum安装软件
  2. REACT day 1
  3. 【LeetCode OJ】Recover Binary Search Tree
  4. 在MAC平台下使用Eclipse出现了中文乱码
  5. WebUI-自用
  6. SQL Server数据库学习笔记-E-R模型
  7. LOVE代码收集
  8. redis百度百科和维基百科知识总结:
  9. Thinking in C++: 第1章 为什么C++会成功
  10. VirtualBox 扩展包卸载或安装失败(VERR_ALREADY_EXISTS)
  11. Catalan数总结
  12. hdu4277 USACO ORZ
  13. 微信浏览器返回刷新,监听微信浏览器返回事件,网页防复制,移动端禁止图片长按和vivo手机点击img标签放大图片
  14. 12 SharedPreferences
  15. java高级 - java利用listener实现回调,即观察者模式
  16. 基于MNIST数据集使用TensorFlow训练一个包含一个隐含层的全连接神经网络
  17. ORB-SLAM2(1) Linux下配置和编译
  18. RabbitMQ的Q&amp;A
  19. ACM__01背包,完全背包,多重背包
  20. linux中inittab文件详解

热门文章

  1. SPI设备的驱动
  2. ajax 将整个表单提交到后台处理
  3. Day 19 函数之闭包、装饰器
  4. 本地安装Sass,Compass
  5. Careercup | Chapter 4
  6. Python之Django-part 1
  7. SilverLight:布局(3)StackPanel 对象
  8. Direct2D教程(二)来看D2D世界中的Hello,World
  9. POJ3114 有些图缩点/改图/最短路
  10. inputclean插件的使用方法