#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
pthread_cond_t cond; // 条件变量,用于实现线程间通信
pthread_mutex_t mutex; // 互斥锁,保证在临界区代码执行时的原子性
typedef struct NODE
{
int num;
struct NODE *next;
} NODE;
NODE *head = NULL;
/**
* 生产者线程函数
* 该函数模拟生产者的行为,不断生产产品(节点),并将其加入到链表中
* @param arg 线程函数的参数,这里未使用
* @return NULL
*/
void *Producer(void *arg)
{
while (1) // 模拟永久循环以持续生产
{
pthread_mutex_lock(&mutex); // 加锁,进入临界区
NODE *newnode = (NODE *)malloc(sizeof(NODE)); // 生产一个新节点
newnode->num = rand() % 1000 + 1; // 为节点赋予随机值,模拟生产行为
newnode->next = head; // 将新节点链接到链表头部
head = newnode;
printf("生产者 id : %d 生产者 number: %d\n", pthread_self(), newnode->num); // 打印生产信息,包括线程ID和节点值
pthread_mutex_unlock(&mutex); // 解锁,退出临界区
// 生产完毕唤醒消费者
pthread_cond_signal(&cond);
sleep(rand() % 3); // 模拟生产者生产速度
}
return NULL;
}
/**
* 消费者线程函数
* 函数模拟消费者的行为,不断从链表中消费产品(节点)
* @param arg 线程函数的参数,这里未使用
* @return NULL
*/
void *Maker(void *arg)
{
while (1) // 模拟永久循环以持续消费
{
pthread_mutex_lock(&mutex); // 加锁,进入临界区
while (head == NULL)
{
// 阻塞消费者线程,等待生产者信号
pthread_cond_wait(&cond, &mutex);
}
NODE *consumer = head;
head = head->next; // 更新 head 指针
printf("消费者 id : %d 消费者 number : %d\n", pthread_self(), consumer->num); // 打印消费信息,包括线程ID和节点值
free(consumer); // 释放已消费的节点内存
pthread_mutex_unlock(&mutex); // 解锁,退出临界区
sleep(rand() % 3); // 模拟消费者消费速度
}
return NULL;
}
int main(int argc, char const *argv[])
{
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
// 定义生产者和消费者线程数量
pthread_t producer[5];
pthread_t maker[5];
for (int i = 0; i < 5; i++)
{
pthread_create(&producer[i], NULL, Producer, NULL); // 创建 5 个生产者线程
}
for (int i = 0; i < 5; i++)
{
pthread_create(&maker[i], NULL, Maker, NULL); // 创建 5 个消费者线程
}
// 等待所有线程执行完毕
for (int i = 0; i < 5; i++)
{
pthread_join(producer[i], NULL);
pthread_join(maker[i], NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
生产者和消费者模拟
最新推荐文章于 2024-10-08 16:57:41 发布