📜  C中的生产者消费者问题(1)

📅  最后修改于: 2023-12-03 15:14:25.290000             🧑  作者: Mango

C中的生产者消费者问题

生产者消费者问题是多线程编程中的典型问题,它描述的是一个生产者、一个消费者和一个缓冲区,在缓冲区中交替进行数据的生产和消费。

问题描述

生产者将新的数据放入缓冲区,而消费者将数据从缓冲区中取出。缓冲区有一个固定大小,且当缓冲区已满时,生产者需要等待;当缓冲区为空时,消费者需要等待。

解决方法

生产者和消费者之间需要同步,以确保数据的正确交替操作。在C语言中,可以使用信号量实现同步和互斥。

以下是基于信号量实现的解决方法:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 10 // 缓冲区大小
#define PRODUCE_TIMES 100 // 生产者生产完成的次数
#define CONSUME_TIMES 100 // 消费者消费完成的次数

int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 缓冲区中的指针
int out = 0; // 缓冲区中的指针

sem_t empty, full, mutex; // 信号量

// 生产者线程
void *producer(void *arg) {
    int i, data;
    for (i = 0; i < PRODUCE_TIMES; i++) {
        data = rand() % 1000;
        sem_wait(&empty); // 等待缓冲区不满
        sem_wait(&mutex); // 等待访问缓冲区互斥
        buffer[in] = data; // 将数据放入缓冲区
        in = (in + 1) % BUFFER_SIZE; // 指针后移
        printf("生产者生产:%d\n", data);
        sem_post(&mutex); // 解除访问缓冲区互斥
        sem_post(&full); // 增加缓冲区中的数据量
    }
    pthread_exit(NULL);
}

// 消费者线程
void *consumer(void *arg) {
    int i, data;
    for (i = 0; i < CONSUME_TIMES; i++) {
        sem_wait(&full); // 等待缓冲区有数据
        sem_wait(&mutex); // 等待访问缓冲区互斥
        data = buffer[out]; // 从缓冲区取出数据
        out = (out + 1) % BUFFER_SIZE; // 指针后移
        printf("消费者消费:%d\n", data);
        sem_post(&mutex); // 解除访问缓冲区互斥
        sem_post(&empty); // 减少缓冲区中的数据量
    }
    pthread_exit(NULL);
}

int main() {
    int i;
    pthread_t producer_thread, consumer_thread;

    srand(time(NULL)); // 初始化随机数种子

    sem_init(&empty, 0, BUFFER_SIZE); // 初始化信号量
    sem_init(&full, 0, 0);
    sem_init(&mutex, 0, 1);

    pthread_create(&producer_thread, NULL, producer, NULL); // 创建线程
    pthread_create(&consumer_thread, NULL, consumer, NULL);

    pthread_join(producer_thread, NULL); // 等待线程结束
    pthread_join(consumer_thread, NULL);

    sem_destroy(&empty); // 销毁信号量
    sem_destroy(&full);
    sem_destroy(&mutex);

    return 0;
}

上述代码中,缓冲区的大小、生产者和消费者的执行次数、信号量的初始值等都可以根据实际情况进行调整。

结论

使用信号量可以有效地解决生产者消费者问题。在实际开发中,还可以使用其他的同步和互斥机制,比如互斥锁、条件变量等。