linux sem 信号量是一种特殊的变量,访问具有原子性, 用于解决进程或线程间对共享资源引发的同步问题。信号量通过一个计数器控制对共享资源的访问,信号量的值是一个非负整数,所有通过它的进程/线程都会将该整数减1。如果计数器大于0,则访问被允许,计数器减1;如果为0,则访问被禁止,所有试图通过它的线程都将处于等待状态。对共享资源使用完毕,计数器加1。
信号量和互斥锁(mutex)的区别:
- 互斥锁只允许一个线程进入临界区,可用于进程/线程的互斥,而信号量允许多个线程同时进入临界区,可用于进程/线程的同步。互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
- 互斥量值只能为0/1,信号量值可以为非负整数。
也就是说,一个互斥量只能用于一个资源的互斥访问,不能实现多个资源的多线程互斥问题,若要对一个资源实现同步访问,可配合条件变量或信号量一起使用。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量,也可以完成一个资源的互斥访问。
#include <semaphore.h>
sem_t sem_event;
int sem_init(sem_t *sem, int pshared, unsigned int value);//初始化一个信号量
int sem_destroy(sem_t * sem);//销毁信号量
int sem_post(sem_t * sem);//信号量增加1
int sem_wait(sem_t * sem);