互斥量(Mutex)数据结构
互斥量表现互斥现象的数据结构,也被看成二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用做同步多任务的行为,它经常使用做保护从中断来的临界段代码而且在共享同步使用的资源。多线程
Mutex 本质上说就是一把锁,提供对资源的独占访问,因此Mutex主要的做用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别表明了 Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程若是试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程能够 Lock临界资源,以后Mutex值减1变为0。并发
Mutex能够被抽象为四个操做:函数
- 建立 Createpost
- 加锁 Lockui
- 解锁 Unlockspa
- 销毁 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. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量能够由一个线程释放,另外一个线程获得。