Linux 内核提供了一个遵守上面语义的旗标实现, 尽管术语有些不同. 为使用旗标, 内核 代码必须包含 <asm/semaphore.h>. 相关的类型是 struct semaphore; 实际旗标可以用 几种方法来声明和初始化. 一种是直接创建一个旗标, 接着使用 sema_init 来设定它:

void sema_init(struct semaphore *sem, int val); 这里 val 是安排给旗标的初始值.

然而, 通常旗标以互斥锁的模式使用. 为使这个通用的例子更容易些, 内核提供了一套帮 助函数和宏定义. 因此, 一个互斥锁可以声明和初始化, 使用下面的一种:

DECLARE_MUTEX(name); DECLARE_MUTEX_LOCKED(name);

这里, 结果是一个旗标变量( 称为 name ), 初始化为 1 ( 使用 DECLARE_MUTEX ) 或者 0 (使用 DECLARE_MUTEX_LOCKED ). 在后一种情况, 互斥锁开始于上锁的状态; 在允许任 何线程存取之前将不得不显式解锁它.

如果互斥锁必须在运行时间初始化( 这是如果动态分配它的情况, 举例来说), 使用下列 中的一个:

void init_MUTEX(struct semaphore *sem);

void init_MUTEX_LOCKED(struct semaphore *sem);

在 Linux 世界中, P 函数称为 down -- 或者这个名子的某个变体. 这里, "down" 指的 是这样的事实, 这个函数递减旗标的值, 并且, 也许在使调用者睡眠一会儿来等待旗标变 可用之后, 给予对被保护资源的存取. 有 3 个版本的 down:

void down(struct semaphore *sem);

int down_interruptible(struct semaphore *sem); int down_trylock(struct semaphore *sem);

down 递减旗标值并且等待需要的时间. down_interruptible 同样, 但是操作是可中断的. 这个可中断的版本几乎一直是你要的那个; 它允许一个在等待一个旗标的用户空间进程被 用户中断. 作为一个通用的规则, 你不想使用不可中断的操作, 除非实在是没有选择. 不 可中断操作是一个创建不可杀死的进程( 在 ps 中见到的可怕的 "D 状态" )和惹恼你的 用户的好方法, 使用 down_interruptible 需要一些格外的小心, 但是, 如果操作是可中 断的, 函数返回一个非零值, 并且调用者不持有旗标. 正确的使用 down_interruptible 需要一直检查返回值并且针对性地响应.

最后的版本 ( down_trylock ) 从不睡眠; 如果旗标在调用时不可用, down_trylock 立 刻返回一个非零值.

一旦一个线程已经成功调用 down 各个版本中的一个, 就说它持有着旗标(或者已经"取得 "或者"获得"旗标). 这个线程现在有权力存取这个旗标保护的临界区. 当这个需要互斥的 操作完成时, 旗标必须被返回. V 的 Linux 对应物是 up:

void up(struct semaphore *sem);

一旦 up 被调用, 调用者就不再拥有旗标.

如你所愿, 要求获取一个旗标的任何线程, 使用一个(且只能一个)对 up 的调用释放它. 在错误路径中常常需要特别的小心; 如果在持有一个旗标时遇到一个错误, 旗标必须在返 回错误状态给调用者之前释放旗标. 没有释放旗标是容易犯的一个错误; 这个结果( 进程 挂在看来无关的地方 )可能是难于重现和跟踪的.

Linux 旗标实现的更多相关文章

  1. linux 读者/写者旗标

    旗标为所有调用者进行互斥, 不管每个线程可能想做什么. 然而, 很多任务分为 2 种清 楚的类型: 只需要读取被保护的数据结构的类型, 和必须做改变的类型. 允许多个并发读 者常常是可能的, 只要没有 ...

  2. Linux 设备驱动 Edition 3

    原文网址:http://oss.org.cn/kernel-book/ldd3/index.html Linux 设备驱动 Edition 3 By Jonathan Corbet, Alessand ...

  3. Linux Device Driver 3th 中的一些坑

    linux设备驱动第三版由于年代比较久远,有很多东西已过时.开一贴记录自己发现的一些问题. 4.3.1.4. seq_file接口 此节最后提到用 struct proc_dir_entry* cre ...

  4. Linux学习日记之磁盘与档案系统

    主要定义 磁盘的物理组成磁盘主要由圆形磁盘(多张).机械手臂.磁头等组成.每张磁盘都有不同的磁道,半径相同的磁道组成了磁柱,沿着中心划线可将磁盘分成若干扇区,每个扇区的大小是512Bytes. 磁盘分 ...

  5. linux 程序管理与SElinux

    此文涉及的命令:&.jobs.fg.bg.kill.nohup.ps.top.pstree.free.uname.uptime.netstat.dmesg.vmstat.fuser.lsof. ...

  6. 每天一个linux命令(41):ps命令

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  7. Windows、Linux下文件操作(写、删除)错误的产生原因、及解决方法

    catalog . 引言 . Linux平台上涉及的File IO操作 . Windows平台上涉及的File IO操作 0. 引言 本文试图讨论在windows.linux操作系统上基于C库进行文件 ...

  8. Linux文件系统(inode、block……)

    内容源于<鸟哥的Linux私房菜> 认识 EXT2 文件系统 文件系统的特殊观察与操作 文件系统 superblock,inode,block superblock,inode,block ...

  9. linux之ps命令

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

随机推荐

  1. qt加载背景图片的一种方式

    //加载背景图片 void LCTGrid::loadBgPicture() { QImage image; QPalette palette; image.load(m_sPicturePath); ...

  2. 【JZOJ3887】【长郡NOIP2014模拟10.22】字符串查询

    haf 给定n个字符串和q个询问 每次询问在这n个字符串中,有多少个字符串同时满足 1. 字符串a是它的前缀 2. 字符串b是它的后缀 100%数据满足n,q≤50000,字符串长度丌超过100,任意 ...

  3. UIScrollView 实践经验

    UIScrollView(包括它的子类 UITableView 和 UICollectionView)是 iOS 开发中最常用也是最有意思的 UI 组件,大部分 App 的核心界面都是基于三者之一或三 ...

  4. js遮罩

    1.1 背景半透明遮罩层样式 需要一个黑色(当然也可以其他)背景,且须设置为绝对定位,以下是项目中用到的css样式: /* 半透明的遮罩层 */ #overlay { background: #000 ...

  5. Linux配置redis开机启动(CentOS 7)

    https://blog.csdn.net/qq_31803503/article/details/79246205 本次配置linux版本是CentOS 7 首先将  redis-3.2.3/uti ...

  6. KiCad EDA 过孔是否可以开窗?

    KiCad EDA 过孔是否可以开窗? 和传统的商业 EDA 不同,KiCad EDA 的过孔默认就是盖绿油. 在 KiCad 的过孔界面没有任何可以设置的地方,这也有一个好处,不过考虑过孔是否盖油. ...

  7. nn.moduleList 和Sequential由来、用法和实例 —— 写网络模型

    对于cnn前馈神经网络如果前馈一次写一个forward函数会有些麻烦,在此就有两种简化方式,ModuleList和Sequential.其中Sequential是一个特殊的module,它包含几个子M ...

  8. DirectEvents用法

    DirectEvents异步执行服务器端事件 我们首先来看一下Ext.Net DirectEvents的一个最简单用法,通过点击按钮触发服务器端的事件处理方法,并在前台弹出一个提示框. <ext ...

  9. C# 星期相关代码实例

    本文为引用文章 仅作整理自用 原文链接: https://www.cnblogs.com/yxyl/p/9992841.html @网吧看压力大 从周一到周日的顺序,获取排序数值: int i = D ...

  10. get_magic_quotes_gpc() PHP转义的真正含义

    如何正确的理解PHP转 义是一个初学者比较困扰的问题.我们今天为大家简要的讲述了PHP转义的具体含义,希望有所帮助.PHP转义一直困扰着我, 今天认真的看了一下PHP手册, 终于解决了. 在PHP中默 ...