1、相关函数
#include <semaphore.h>
// 初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
// 加锁信号量
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
// 解除信号量
int sem_post(sem_t *sem);
2、信号量示例实现生产者&消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM 5 // 定义最大信号量
// 定义数据模型
struct object{
int num;
};
// 生产消息数据结构
struct object* queue[NUM];
// 1、定义2个信号量(生产&消费)
sem_t consumer, producer;
// 消息者函数主体
void *consume(void *arg){
int i = 0;
while(1){
// 消费者应该等待生产者的信号量释放,没有生产就没有消费
sem_wait(&producer);
// 消费掉一个量
struct object *obj = queue[i];
printf("consumer ----- %d |", obj->num);
queue[i] = NULL;
// 打印当前还剩下的待消费量
int j = i+1;
struct object *p = queue[j%NUM];
while(p){
printf(" %d", p->num);
p = queue[++j%NUM];
}
putchar('\n');
// 增加一个消费量
sem_post(&consumer);
usleep(rand()%500000);
free(obj);
i = ++i % NUM;
}
}
// 生产者函数主体
void *production(void *arg){
int i = 0;
while(1){
// 等待消费信号量(消费信号量初始为5)
sem_wait(&consumer);
// 有需求才生产
struct object *obj = malloc(sizeof(struct object));
obj->num = rand() & 99;
// 生产出来的产品循环挂到队列中
queue[i] = obj;
printf("producer ----- %d\n", obj->num);
// 增加一个生产量
sem_post(&producer);
usleep(rand()%500000);
i = ++i % NUM;
}
}
int main(){
// 产生一个随机数种子
srand(time(NULL));
// 初始化两个信号量
sem_init(&consumer, 0, NUM);
sem_init(&producer, 0, 0);
// 初始化2个线程,分别模拟生产与消费
pthread_t tid_c, tid_p;
pthread_create(&tid_c, NULL, consume, NULL);
pthread_create(&tid_p, NULL, production, NULL);
// 主线程合并(回收)两个子线程
pthread_join(tid_c, NULL);
pthread_join(tid_p, NULL);
// 信号量使用后及时释放销毁
sem_destroy(&consumer);
sem_destroy(&producer);
return 0;
}
执行结果:
parallels@ubuntu:~/Linux/sem$ ./sem.out
producer ----- 98
consumer ----- 98 |
producer ----- 34
producer ----- 1
consumer ----- 34 | 1
consumer ----- 1 |
producer ----- 98
producer ----- 2
consumer ----- 98 | 2
consumer ----- 2 |
producer ----- 35
consumer ----- 35 |
producer ----- 0
producer ----- 96
consumer ----- 0 | 96
producer ----- 98
consumer ----- 96 | 98
producer ----- 35
producer ----- 1
consumer ----- 98 | 35 1
producer ----- 99
producer ----- 1
producer ----- 3
consumer ----- 35 | 1 99 1 3
consumer ----- 1 | 99 1 3
consumer ----- 99 | 1 3
producer ----- 32
consumer ----- 1 | 3 32
producer ----- 65
consumer ----- 3 | 32 65
producer ----- 0
producer ----- 3
consumer ----- 32 | 65 0 3
producer ----- 96
consumer ----- 65 | 0 3 96
producer ----- 98
producer ----- 96
consumer ----- 0 | 3 96 98 96
consumer ----- 3 | 96 98 96
producer ----- 97
consumer ----- 96 | 98 96 97
consumer ----- 98 | 96 97
consumer ----- 96 | 97
consumer ----- 97 |
producer ----- 0
consumer ----- 0 |
producer ----- 66
consumer ----- 66 |
producer ----- 35
producer ----- 65
producer ----- 97
consumer ----- 35 | 65 97
^C
parallels@ubuntu:~/Linux/sem$