信号量学习总结(一)
定义
信号量是一种用于如果不同进程间或一个给定进程的不同线程间同步的原语。
信号量相关的操作
创建一个信号量
创建一个新的有名信号量或打开一个已存在的有名信号量。
sem_t*sem_open(const char *name, int oflag);
sem_t*sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
oflag:可以是0、O_CREAT或O_CREAT |O_EXCL。
如果指定了O_CREAT标志,第三和第四个参数是需要的。mode参数为信号量权限位。value参数为信号量初始值。
关闭信号量
int sem_close(sem_t *sem);
关闭一个信号量并没有将它从系统中删除。
删除信号量
int sem_unlink(const char *name);
等到最后一个sem_close操作才将信号量从系统内核中删除。
同步原语
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
进程或线程使用临界资源时,测试所指定信号量的值,如果该值大于0,那就将它减1并立即返回。
如果返回值等于0,调用线程就被投入睡眠中,直到信号量值变为大于0,这时再将信号量值减一,函数随后返回。
sem_wait和sem_trywait的区别:当信号量的值已经是0时,sem_trywait并不将调用线程投入睡眠。它返回一个EAGAIN错误。
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem,int *valp);
进程或线程使用完临界资源后,应该调用sem_post函数。
sem_getvalue在由valp指向的整数中返回指定信号量sem的当前值。如果信号量当前已上锁,那么返回值或为0,或为某个负数,其绝对值就是等待该信号量解锁的线程数。
互斥锁、信号量、条件变量之间的三个区别。
1)互斥锁必须总是由给它上锁的线程解锁,信号量的挂出(sem_post操作)却不必由执行过它的等待操作(sem_wait操作)的同一个线程执行。
2)互斥锁要么被解锁,要么被解开(二值状态,类似于二值信号量)
3)信号量有一个与之关联的状态(信号量计数值),因此信号量挂出操作总是被记住。但是,当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么信号将丢失。