1. 条件变量+互斥锁 实现 生产者-消费者模型:
/*借助条件变量模拟 生产者-消费者 问题*/ #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> /*链表作为公享数据,需被互斥量保护*/ //模拟箩筐 struct msg { struct msg *next; int num; }; struct msg *head; struct msg *mp; /* 静态初始化 一个条件变量 和 一个互斥量*/ pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; //条件变量静态初始化 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; //互斥锁静态初始化 void *consumer(void *p)//消费者 { for (;;) { pthread_mutex_lock(&lock);//加锁 while (head == NULL) { //头指针为空,说明没有节点 可以为if吗 pthread_cond_wait(&has_product, &lock); } mp = head; head = mp->next; //模拟消费掉一个产品 pthread_mutex_unlock(&lock);//解锁 printf("-Consume ---%d ", mp->num); free(mp); mp = NULL; sleep(rand() % 5); } } void *producer(void *p)//生产者 { for (;;) { mp = malloc(sizeof(struct msg)); mp->num = rand() % 1000 + 1; //模拟生产一个产品 printf("-Produce ---%d ", mp->num); pthread_mutex_lock(&lock);//加锁 mp->next = head;//头插法 head = mp; pthread_mutex_unlock(&lock);//解锁 pthread_cond_signal(&has_product); //将等待在该条件变量上的一个线程唤醒 sleep(rand() % 5); } } int main(int argc, char *argv[]) { pthread_t pid, cid; srand(time(NULL)); pthread_create(&pid, NULL, producer, NULL);//创建生产者线程 pthread_create(&cid, NULL, consumer, NULL);//创建消费者线程 pthread_join(pid, NULL);//回收线程 pthread_join(cid, NULL); return 0; }
2. 信号量 实现 生产者-消费者模型:
/*信号量实现 生产者 消费者问题*/ #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <semaphore.h> #define NUM 5 int queue[NUM]; //全局数组实现环形队列 sem_t blank_number, product_number; //空格子信号量, 产品信号量 void *producer(void *arg) { int i = 0; while (1) { sem_wait(&blank_number); //生产者将空格子数--,为0则阻塞等待 queue[i] = rand() % 1000 + 1; //生产一个产品,存入队列 printf("----Produce---%d ", queue[i]); sem_post(&product_number); //将产品数++ i = (i+1) % NUM; //借助下标实现环形,下标往后移 sleep(rand()%3); } } void *consumer(void *arg) { int i = 0; while (1) { sem_wait(&product_number); //消费者将产品数--,为0则阻塞等待 printf("-Consume---%d ", queue[i]); queue[i] = 0; //消费一个产品 sem_post(&blank_number); //消费掉以后,将空格子数++ i = (i+1) % NUM; sleep(rand()%3); } } int main(int argc, char *argv[]) { pthread_t pid, cid; sem_init(&blank_number, 0, NUM); //初始化空格子信号量为5 sem_init(&product_number, 0, 0); //产品数为0 pthread_create(&pid, NULL, producer, NULL); //创建生产者线程 pthread_create(&cid, NULL, consumer, NULL); //创建消费者线程 pthread_join(pid, NULL); //回收线程 pthread_join(cid, NULL); sem_destroy(&blank_number); //销毁信号量 sem_destroy(&product_number); return 0; }