semaphore工作原理与应用

一、信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区。

Semaphore分为单值多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。

工作原理: 以一个停车场是运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。

在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

更进一步,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作Wait(等待)Release(释放)。 当一个线程调用Wait(等待)操作时,它要么通过然后将信号量减一,要么一直等下去,直到信号量大于一或超时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为加操作实际上是释放了由信号量守护的资源。

NOTE:临界区: 每个进程中访问临界资源的那段代码称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。

不多做解释,要使用信号量同步,需要包含头文件semaphore.h

二、主要用到的函数:

1.sem_init
int sem_init(sem_t *sem, int pshared, unsigned int value);

其中sem是要初始化的信号量,pshared表示此信号量是在进程间共享还是线程间共享,pshared控制信号量的类型,如果其值为0,就表示这个信号量是当前进程的局部信号量,否则信号量就可以在多个进程之间共享;value是信号量的初始值,一般设置为0。调用成功时返回0,失败返回-1.

该函数初始化由sem指向的信号对象,设置它的共享选项,并给它一个初始的整数值,可通过如下联合体设置:

sem_t sem_event;
2. sem_wait
int sem_wait(sem_t *sem);

等待信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0,则线程阻塞。相当于P操作。成功返回0,失败返回-1, 原子操作。

3. sem_post
int sem_post(sem_t *sem); 

释放信号量,让信号量的值加1。相当于V操作,原子操作。

4. sem_destroy
int sem_destroy(sem_t *sem);

其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy销毁。

猜你喜欢

转载自blog.csdn.net/liuxiaodong400/article/details/88659106