# 互斥锁和信号量

Mutex是一把钥匙，一个人拿了就可进入一个房间，出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问，保证这段代码不会被并行的运行。

Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.

Officially: "Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section."

Semaphore是一件可以容纳N人的房间，如果人不满就可以进去，如果人满了，就要等待有人出来。对于N=1的情况，称为binary semaphore。一般的用法是，用于限制对于某一资源的同时访问。

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.

Officially: "A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore)." Ref: Symbian Developer Library

1、Mutex 互斥量/互斥锁

Mutex本质上说就是一把锁，提供对资源的独占访问，所以Mutex的主要作用是用于互斥的访问共享资源

Mutex对象的值，只有0和1两个值。这两个值也分别代表了Mutex的两种状态。

Mutex可以被抽象为四个操作：创建 Create；加锁 Lock；解锁 Unlock；销毁 Destroy。

Mutex被创建时可以有初始值，表示Mutex被创建后，是锁定状态还是空闲状态。

-- 对共享资源操作前一定要获得锁。

-- 完成操作以后一定要释放锁。

-- 尽量短时间的占用锁，即占用锁的时间不要过长。

-- 如果有多锁，如获得顺序是ABC连环扣，释放顺序也应该是ABC。

-- 线程错误返回时应该释放它所获得的锁。

>>“挂起等待”和“唤醒等待线程”的操作？

2、信号量 semaphore

-- 二进制信号量（binary semaphore）：只允许信号量取0或1值，其同时只能被一个线程获取。

-- 整型信号量（integer semaphore）：信号量取值是整数，它可以被多个线程同时获得，直到信号量的值变为0.

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

Semaphore可以被抽象为5个操作：

>> 创建 Create

>> 等待 Wait，线程等待信号量，如果值>0，则获得，值减1；如果<=0，则线程进入睡眠状态，直到信号量值>0或超时。

>> 释放 Post，执行释放信号量，则值加+1，如果此时有正在等待的线程，则唤醒该线程。

>> 试图等待 TryWait，线程并不真正的去获得信号量，而是检查信号量是否能够被获得，如果信号量值大于0，则TryWait返回成功，否则返回失败。

>> 销毁 Destroy

POSIX Semaphore（Named Semaphores / Unnamed Semaphores）

Named Semaphores：this type of semaphore has a name. By calling sem_open() with the same name, unrelated process can access the same semaphore.

To work with a named semaphore, we employ the following functions:

-- The sem_open() function opens or create a semaphore, initializes the semaphore if it is created by the call, and returns a handle for use in later calls.

-- The sem_post(sem) and sem_wait(sem) functions respectively increment and decrement a semaphore's value.

-- The sem_getvalue() function retrieves a semaphore's current value.

-- The sem_close() function removes the calling process's association with a semaphore that it previously opened.

-- The sem_unlink() function removes a semaphore name and marks the semaphore for deletion when all processes have closed it.

3）互斥量和信号量的区别：

>> 互斥量用于线程的互斥，信号量用于线程的同步。

>> 互斥量值只能是0/1，信号量值可以为非负整数。

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