文档章节

互斥量与信号量

雨中人X
 雨中人X
发布于 2016/11/09 10:29
字数 1629
阅读 23
收藏 1

互斥量(Mutex)

互斥量表现互斥现象的数据结构,也被当作二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源。

clip_image001

 

Mutex 本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别代表了 Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程可以 Lock临界资源,之后Mutex值减1变为0。

Mutex可以被抽象为四个操作:

- 创建 Create

- 加锁 Lock

- 解锁 Unlock

- 销毁 Destroy

Mutex被创建时可以有初始值,表示Mutex被创建后,是锁定状态还是空闲状态。在同一个线程中,为了防止死锁,系统不允许连续两次对Mutex加锁(系统一般会在第二次调用立刻返回)。也就是说,加锁和解锁这两个对应的操作,需要在同一个线程中完成。

不同操作系统中提供的Mutex函数:

动作\系统

Win32

Linyx

Solaris

创建

CreateMutex

pthread_mutex_init

mutex_init

加锁

WaitForSingleObject

pthread_mutex_lock

mutex_lock

解锁

ReleaseMutex

pthread_mutex_unlock

mutex_unlock

销毁

CloseHandle

pthread_mutex_destroy

mutex_destroy

信号量

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

信号量可以分为几类:

² 二进制信号量(binary semaphore):只允许信号量取0或1值,其同时只能被一个线程获取。

² 整型信号量(integer semaphore):信号量取值是整数,它可以被多个线程同时获得,直到信号量的值变为0。

² 记录型信号量(record semaphore):每个信号量s除一个整数值value(计数)外,还有一个等待队列List,其中是阻塞在该信号量的各个线程的标识。当信号量被释 放一个,值被加一后,系统自动从等待队列中唤醒一个等待中的线程,让其获得信号量,同时信号量再减一。

信号量通过一个计数器控制对共享资源的访问,信号量的值是一个非负整数,所有通过它的线程都会将该整数减一。如果计数器大于0,则访问被允许,计数器减1;如果为0,则访问被禁止,所有试图通过它的线程都将处于等待状态。

计 数器计算的结果是允许访问共享资源的通行证。因此,为了访问共享资源,线程必须从信号量得到通行证, 如果该信号量的计数大于0,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。当此线程不再需要访问共享资 源时,它释放该通行证,这导致信号量的计数递增,如果另一个线程等待通行证,则那个线程将在那时获得通行证。

 

Semaphore可以被抽象为五个操作:

- 创建 Create

- 等待 Wait:

线程等待信号量,如果值大于0,则获得,值减一;如果只等于0,则一直线程进入睡眠状态,知道信号量值大于0或者超时。

-释放 Post

执行释放信号量,则值加一;如果此时有正在等待的线程,则唤醒该线程。

-试图等待 TryWait

如果调用TryWait,线程并不真正的去获得信号量,还是检查信号量是否能够被获得,如果信号量值大于0,则TryWait返回成功;否则返回失败。

-销毁 Destroy

信 号量,是可以用来保护两个或多个关键代码段,这些关键代码段不能并发调用。在进入一个关键代码段之前,线程必须获取一个信号量。如果关键代码段中没有任何 线程,那么线程会立即进入该框图中的那个部分。一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程 释放信号量。为了完成这个过程,需要创建一个信号量,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

动作\系统

Win32

POSIX

创建

CreateSemaphore

sem_init

等待

WaitForSingleObject

sem _wait

释放

ReleaseMutex

sem _post

试图等待

WaitForSingleObject

sem _trywait

销毁

CloseHandle

sem_destroy

 

互斥量和信号量的区别

1. 互斥量用于线程的互斥,信号线用于线程的同步。

这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

2. 互斥量值只能为0/1,信号量值可以为非负整数。

也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。

本文转载自:http://blog.chinaunix.net/uid-10008293-id-2972285.html

共有 人打赏支持
雨中人X
粉丝 8
博文 57
码字总数 15326
作品 0
深圳
高级程序员
私信 提问
SylixOS与Linux接口对应关系之一

1. 适用范围 本文档可作为Linux驱动源码或库源码快速移植至SylixOS的参考。 2. 互斥信号量 2.1 概念简介 互斥信号量(Linux中亦称为互斥锁)是因为多线程对临界区访问而存在的。只有拥有互斥...

zhywxyy
2017/05/15
0
0
秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题

秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题 在《秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量》中对经典多线程同步互斥问题进行了回顾和总结,这篇文章对...

长平狐
2012/12/10
148
0
操作系统清华大学版笔记(十) 信号量、管程、条件互斥、经典同步问题(读者写者、哲学家问题)

10-1 信号量 Semaphore 一个整型int(sem),可进行两个原子操作 P() sem–,如果sem<0,等待,否则继续,类似lock_acquire V() sem++,如果sem<=0,说明当前有等着的,唤醒挂在信号量上的进...

xiaoshuaisdl
2018/04/10
0
0
C++ 模拟生产者与消费者模式等

设计并实现一个进程,该进程拥有一个生产者线程和一个消费者线程,它们使用N个不同的缓冲区(N为一个确定的数值,例如N=32)。需要使用如下信号量: 一个互斥信号量,用以阻止生产者线程和消...

日生三金
2017/11/25
0
0
rt-thread的IPC机制之信号量源码分析

rt-thread操作系统的IPC(Inter-Process Communication,进程间通信)包含有信号量,互斥锁,事件,邮箱,消息队列. 本文主要针对信号量.信号量是用来解决线程同步和互斥的通用工具,和互斥量类似...

长平狐
2013/03/19
357
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 做一只舔狗,开心时就去舔她,不开心时就舔自己

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @温家成 :分享连诗雅的单曲《水星逆行》 《水星逆行》- 连诗雅 手机党少年们想听歌,请使劲儿戳(这里) @罗马的王 :在家嫌猫吵,去书城看书...

小小编辑
35分钟前
24
3
Ruby中的继承、原型、面向对象、访问域

先有类还是先有对象 从鸡蛋悖论解决可以悟到一个道理,不要从常识上假设非此即彼和绝对静止。 Ruby中的类和对象正是这么个东西 我们创建一个类,那它就是Class这个对象的实例,而Class,于是...

可数局部基
今天
5
0
什么时候使用字节流、什么时候使用字符流,二者的区别

在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。 InputStream 和OutputStream,...

watermelon11
今天
6
0
Alpakka Kafka,反应式Kafka客户端

Alpakka Kafka 是一个要用于 Java 和 Scala 语言的开源的流感知和反应式集成数据线项目。它建立在 Akka Stream之上,提供了 DSL 来支持反应式和流式编程,内置回压功能。Akka Streams 是 Re...

羊八井
今天
5
0
PHP7源码编译安装详解

$ yum groupinstall "development tools"$ yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype \freetype-devel libpng libpng-devel libxml2 ......

问题终结者
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部