posix信号量

信号量是一种用于提供不同进程间或者一个给定进程的不同线程间同步手段的原语。

基本操作

posix信号量是计数信号量,它提供以下三种基本操作:

有名与无名

posix信号量可以是有名的,也可以是基于内存的,区别如下:

在编码上,两者的函数调用也有些区别。

        有名信号量                        基于内存信号量
        sem_open                          sem_init
                        sem_wait
                        sem_trywait
                        sem_post
                        sem_get_value
        sem_close                         sem_destroy
        sem_unlink

对比互斥锁和条件变量

计数值只能取0和1的信号量也称为二值信号量,二值信号量可用于互斥,就像互斥锁一样。

初始化信号量为1
sem_wait(&sem);
临界区
sem_post(&sem);

对应互斥锁的代码如下:

初始化互斥锁
pthread_mutex_lock(&mutex);
临界区
pthread_mutex_unlock(&mutex);

互斥锁必须总是由锁住它的线程解锁,而信号量的挂出却不必由执行过它的等待操作的同一线程执行。以生产者-消费者问题为例,生产者伪代码如下:

将信号量get初始化为0
将信号量put初始化为1

for (;;) {
    sem_wait(&put);
    把数据放入缓冲区
    sem_post(&get);
}

消费者伪代码如下:

for (;;) {
    sem_wait(&get);
    处理缓冲区中的数据
    sem_post(&put);
}

由于信号量是计数,挂出操作总是能被记住,而当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么该信号将丢失。

编程接口

#include <semaphore.h>

sem_t* sem_open(const char *name, int oflag);
sem_t* sem_open(const char *name, int oflag, mode_t mode, unsinged int value);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);

int sem_init(sem_t *sem, int shared, unsigned int value);
int sem_destroy(sem_t *sem);

int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem, int *val);
Table of Contents