生产者消费者模型是多线程案例中经常用到的一种模型,有专门的线程在负责生产产品(这个产品指代程序所需的数据、文件等等),有专门的线程在负责取出生产出来的产品用以提供程序使用(消费)。因为生产和消费在程序中是不定时间的,我们也无法确定什么时候需要生产产品,什么时候需要消费产品。所以就有了使用条件变量实现的解决方案。
代码语言:javascript复制#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct tag_product {
struct tag_product* next;
int data;
};
struct tag_product* head;
// 初始化条件变量和锁的另外一种方式,也可以使用init
pthread_cond_t product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* producer(void* arg)
{
struct tag_product* cur;
while (1)
{
// 加锁
pthread_mutex_lock(&mutex);
// 创建新节点
cur = (struct tag_product*)malloc(
sizeof(struct tag_product));
// 让新节点先有所指向
cur->next = head->next;
// 让头节点指向新来的节点
head->next = cur;
// 解锁
pthread_mutex_unlock(&mutex);
// 让其他线程得到新产品通知
pthread_cond_signal(&product);
sleep(rand() % 5);
}
return (void*)0;
}
void* consumer(void* arg)
{
printf(“consumer thread = %dn”, (unsigned int)pthread_self());
struct tag_product* tmp;
while(1)
{
// 加锁
pthread_mutex_lock(&mutex);
while(head->next == NULL)
{
// 等待,循环判断头节点是否有下一个节点
pthread_cond_wait(&product, &mutex);
}
// 有新节点则备份第一个节点
tmp = head->next;
// 让头节点跳过第一个节点
head->next = tmp->next;
// 打印第一个节点的数据
printf(“consumer %dn”, tmp->data);
// 释放第一个节点
free(tmp);
// 解锁
pthread_mutex_unlock(&mutex);
sleep(rand() % 5);
}
return (void*)0;
}
int main(int argc, char* argv[])
{
pthread_t pid, cid;
srand(time(NULL));
head = (struct tag_product*)malloc(sizeof(struct tag_product));
head->next = NULL;
pthread_create(&pid, NULL, producer, (void*)1);
pthread_create(&cid, NULL, consumer, (void*)1);
pthread_join(pid,NULL);
pthread_join(cid,NULL);
return 0;
}