旗标为所有调用者进行互斥, 不管每个线程可能想做什么. 然而, 很多任务分为 2 种清 楚的类型: 只需要读取被保护的数据结构的类型, 和必须做改变的类型. 允许多个并发读 者常常是可能的, 只要没有人试图做任何改变. 这样做能够显著提高性能; 只读的任务可 以并行进行它们的工作而不必等待其他读者退出临界区.

Linux 内核为这种情况提供一个特殊的旗标类型称为 rwsem (或者" reader/writer semaphore"). rwsem 在驱动中的使用相对较少, 但是有时它们有用.

使用 rwsem 的代码必须包含 <linux/rwsem.h>. 读者写者旗标 的相关数据类型是 struct rw_semaphore; 一个 rwsem 必须在运行时显式初始化:

void init_rwsem(struct rw_semaphore *sem);

一个新初始化的 rwsem 对出现的下一个任务( 读者或者写者 )是可用的. 对需要只读存 取的代码的接口是:

void down_read(struct rw_semaphore *sem);

int down_read_trylock(struct rw_semaphore *sem); void up_read(struct rw_semaphore *sem);

对 down_read 的调用提供了对被保护资源的只读存取, 与其他读者可能地并发地存取. 注意 down_read 可能将调用进程置为不可中断的睡眠. down_read_trylock 如果读存取 是不可用时不会等待; 如果被准予存取它返回非零, 否则是 0. 注意 down_read_trylock 的惯例不同于大部分的内核函数, 返回值 0 指示成功. 一个使用 down_read 获取的 rwsem 必须最终使用 up_read 释放.

读者的接口类似:

void down_write(struct rw_semaphore *sem);

int down_write_trylock(struct rw_semaphore *sem); void up_write(struct rw_semaphore *sem);

void downgrade_write(struct rw_semaphore *sem);

down_write, down_write_trylock, 和 up_write 全部就像它们的读者对应部分, 除了, 当然, 它们提供写存取. 如果你处于这样的情况, 需要一个写者锁来做一个快速改变, 接 着一个长时间的只读存取, 你可以使用 downgrade_write 在一旦你已完成改变后允许其 他读者进入.

一个 rwsem 允许一个读者或者不限数目的读者来持有旗标. 写者有优先权; 当一个写者 试图进入临界区, 就不会允许读者进入直到所有的写者完成了它们的工作. 这个实现可能 导致读者饥饿 -- 读者被长时间拒绝存取 -- 如果你有大量的写者来竞争旗标. 由于这个 原因, rwsem 最好用在很少请求写的时候, 并且写者只占用短时间.

linux 读者/写者旗标的更多相关文章

  1. linux 读者/写者自旋锁

    内核提供了一个自旋锁的读者/写者形式, 直接模仿我们在本章前面见到的读者/写者旗标. 这些锁允许任何数目的读者同时进入临界区, 但是写者必须是排他的存取. 读者写者锁有 一个类型 rwlock_t, ...

  2. OS: 读者写者问题(写者优先+LINUX+多线程+互斥量+代码)(转)

    一. 引子 最近想自己写个简单的 WEB SERVER ,为了先练练手,熟悉下在LINUX系统使用基本的进程.线程.互斥等,就拿以前学过的 OS 问题开开刀啦.记得当年学读者写者问题,尤其是写者优先的 ...

  3. Linux 旗标实现

    Linux 内核提供了一个遵守上面语义的旗标实现, 尽管术语有些不同. 为使用旗标, 内核 代码必须包含 <asm/semaphore.h>. 相关的类型是 struct semaphor ...

  4. Linux多线程实践(6) --Posix读写锁解决读者写者问题

    Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *rest ...

  5. linux 一个写缓存例子

    我们已经几次提及 shortprint 驱动; 现在是时候真正看看. 这个模块为并口实现一个非 常简单, 面向输出的驱动; 它是足够的, 但是, 来使能文件打印. 如果你选择来测试这个 驱动, 但是, ...

  6. 读者写者问题继 读写锁SRWLock

    在<秒杀多线程第十一篇读者写者问题>文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法--读写锁SRWLock来解决这一 ...

  7. 读者写者问题(有bug 后续更改)

    与上一篇<秒杀多线程第十篇 生产者消费者问题>的生产者消费者问题一样,读者写者也是一个非常著名的同步问题.读者写者问题描述非常简单,有一个写者很多读者,多个读者可以同时读文件,但写者在写文 ...

  8. Java实现生产者消费者问题与读者写者问题

    摘要: Java实现生产者消费者问题与读者写者问题 1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从 ...

  9. 多线程面试题系列(14):读者写者问题继 读写锁SRWLock

    在第十一篇文章中我们使用事件和一个记录读者个数的变量来解决读者写者问题.问题虽然得到了解决,但代码有点复杂.本篇将介绍一种新方法--读写锁SRWLock来解决这一问题.读写锁在对资源进行保护的同时,还 ...

随机推荐

  1. Linux之脚本安装包

    1.脚本安装包 脚本安装包不是独立的软软件包类型,常见的安装时源码包 是人为把安装过程写成了自动安装的脚本,只要执行脚本,定义简单的参数,就可以完成安装 类似于windows下的软件安装 一般是硬件驱 ...

  2. 大数据技术之Kafka

    Kafka概述 1.1 消息队列     (1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除) 点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息 ...

  3. Directx11教程(59) tessellation学习(1)

    原文:Directx11教程(59) tessellation学习(1)       在D3D11管线中,新增加了3个stage, Hull shader, Tessellator, Domain s ...

  4. 关于element-ui的弹框问题

    el-dialog获取数据. el-dialog加载到页面中的时候,其实已经加载好了.只是默认隐藏了. 第一次点击的时候弹出,为何拿不到数据?之后再次操作就一点问题都没有了.

  5. Date日期类,Canlendar日历类,Math类,Random随机数学类

    Date日期类,SimpleDateFormat日期格式类 Date  表示特定的时间,精确到毫秒 常用方法 getTime() setTime() before() after() compareT ...

  6. Python学习之路12☞模块与包

    一 模块 1.1 什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 1.2 为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前 ...

  7. OpenCV在各版本上的安装教程

    目录 使用pip安装OpenCV 安装Python版的OpenCV 4 安装Python版的OpenCV 3 在OSX和 macOS上安装OpenCV 3 在Ubuntu上安装Python版的Open ...

  8. Person Re-identification 系列论文笔记(三):Improving Person Re-identification by Attribute and Identity Learning

    Improving Person Re-identification by Attribute and Identity Learning Lin Y, Zheng L, Zheng Z, et al ...

  9. Skiing 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题(拓扑序求有向图最长路)

    参考博客(感谢博主):http://blog.csdn.net/yo_bc/article/details/77917288 题意: 给定一个有向无环图,求该图的最长路. 思路: 由于是有向无环图,所 ...

  10. CTR+A组合键 以及终止按键事件传递

    Key UP 或Down 事件中 实现CTR+A全选 if ( Control.ModifierKeys==Keys.Control && e.KeyCode == Keys.A)   ...