#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#define N 5
void sys_err(const char *msg) {
}
// 定义一个队列, 全局数组实现环形队列
int queue[N];
// 定义产品信号量 和 空格子信号量
sem_t sem_product, sem_blank;
// 生产者
void * producer(void *arg) {
int i = 0;
while(1) {
// 阻塞等待有可用的 blank
sem_wait(&sem_blank);
// 随机产生一个产品
queue[i] = rand() % 1000 + 1;
// 打印输出产生的产品
printf("-----produce: %d \n", queue[i]);
// 产品已产生, 可以释放一个 product. 可以理解为sem_product++
sem_post(&sem_product);
// 设置 i 循环
i = (i + 1) % N;
sleep(rand() % 1);
}
// return NULL;
}
// 消费者
void * consumer(void *arg) {
int i = 0;
while(1) {
// 消费者调用 sem_wait() 对产品阻塞
sem_wait(&sem_product);
// 打印获取到的产品
printf("----------------------consumer: %d \n", queue[i]);
// 将该位置的产品设置为 0, 表示该位置已经空出来了
queue[i] = 0;
// 成功拿走一个 product, 则释放出了一个 blank
sem_post(&sem_blank);
// 让 i 从 0 到 4 循环往复
i = (i + 1) % N;
sleep(rand() % 3);
}
// return NULL;
}
/* 生产者需要的是 blank, 当blank 都被填满的时候就阻塞了 */
/* 消费者需要的是 product, 当没有 product 的时候(即5个都是 blank)时,就阻塞了 */
/* 当消费者拿走一个 product 后,就空出了一个 blank, 所以可以释放一个 blank
同理,当生产者产生一个 product 后,就多个一个产品, 所以可以释放一个 product
*/
int main(int argc, const char * argv[]) {
pthread_t pid, cid;
// 初始化 sem_blank 信号量为 5, 且为线程间共享
sem_init(&sem_blank, 0, N);
// 初始化 sem_product 信号量为0 , 且为线程间共享
sem_init(&sem_product, 0, 0);
// 创建生产者和消费者两个子线程
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
// 回收两个子线程
pthread_join(pid, NULL);
pthread_join(cid, NULL);
// 回收两个信号量
sem_destroy(&sem_blank);
sem_destroy(&sem_product);
return 0;
}
标签:product,include,Linux,blank,信号量,semaphore,sem,NULL
From: https://www.cnblogs.com/zxhoo/p/17065895.html