1.概述
信号量(semaphore)是一种提供不同进程间或者一个给定进程不同线程之间的同步。
依然分为POSIX信号量和SystemV信号量,这里先学习POSIX信号量。
POSIX信号量又分为有名信号量和基于内存的信号量(无名信号量)。区别在于是否需要使用POSIX IPC名字来标识。
NOTE:Linux操作系统中,POSIX有名信号量创建在虚拟文件系统中 一般挂载在/dev/shm,其名字以sem.somename的形式存在。
2.信号量操作
早在学操作系统那会,就直到信号量的PV操作,总结一下大概是这么回事:
P操作,也叫做等待(wait)一个信号量,该操作会测试信号量的值,如果其值小于或等于0,将把当前进程/线程投入睡眠,当该信号量变得大于0后就将它减1。
伪代码如下,这两步必须是原子操作。
while(sem <=0);
sem--;
V操作,挂出(post)一个信号量,该操作将信号量值加1
伪代码如下:
sem++;
信号量初始化的值的大小一般用于表示可用资源的数(例如缓冲区大小,之后代码中体现);如果初始化为1,则称之二值信号量,二值信号量的功能就有点像互斥锁了。
不同的是:互斥锁的加锁和解锁必须在同一线程执行,而信号量的挂出却不必由执行等待操作的线程执行。
3.POSIX信号量编程
POSIX信号量编程,离不开以下函数:
1.sem_init()
初始化无名信号量
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
//pshared指定该信号量用于进程还是线程同步
//0-表示用于线程同步(所有线程可见)
//非0-表示用于进程同步(需要放在共享内存中)
2.sem_open()
初始化有名信号量
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
Link with -pthread.
//套路跟之前的消息队列类似
//oflag可以设置为O_CREAT | O_EXCL (如果存在则返回错误)。
//mode可以设置为0644 自己可读写,其他用户和组内用户可读
//value表示信号量初始化的值
3.sem_wait()
和sem_post()
等待和挂出函数
#include