由于题目涉及到线程和条件变量的操作,需要使用多线程库 pthread.h,以下是一个可能的实现:

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

#define MAX_ITEMS 10
#define PRODUCER_NUM 3
#define CONSUMER_NUM 2

struct item {
    int id;
    struct item *next;
};

struct queue {
    struct item *head;
    struct item *tail;
    int num_items;
    pthread_mutex_t lock;
    pthread_cond_t not_full;
    pthread_cond_t not_empty;
};

int get_random_id() {
    return rand() % 1000; // 随机数区间 [0, 999]
}

void *producer(void *arg) {
    struct queue *q = (struct queue *) arg;
    while (1) {
        sleep(3);

        pthread_mutex_lock(&q->lock);
        while (q->num_items == MAX_ITEMS) {
            pthread_cond_wait(&q->not_full, &q->lock);
        }

        struct item *new_item = malloc(sizeof(struct item));
        new_item->id = get_random_id();
        new_item->next = NULL;

        if (q->num_items == 0) {
            q->head = new_item;
        } else {
            q->tail->next = new_item;
        }
        q->tail = new_item;
        q->num_items++;

        printf("Producer %ld: produced item %d\n", pthread_self(), new_item->id);

        pthread_cond_signal(&q->not_empty);
        pthread_mutex_unlock(&q->lock);
    }
    return NULL;
}

void *consumer(void *arg) {
    struct queue *q = (struct queue *) arg;
    sleep(5); // 先睡眠5秒
    while (1) {
        sleep(1);

        pthread_mutex_lock(&q->lock);
        while (q->num_items == 0) {
            pthread_cond_wait(&q->not_empty, &q->lock);
        }

        struct item *item_to_consume = q->head;
        q->head = item_to_consume->next;
        q->num_items--;
        if (q->num_items == 0) {
            q->tail = NULL;
        }

        printf("Consumer %ld: consumed item %d\n", pthread_self(), item_to_consume->id);

        free(item_to_consume);

        pthread_cond_signal(&q->not_full);
        pthread_mutex_unlock(&q->lock);
    }
    return NULL;
}

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

    struct queue q = {
        .head = NULL,
        .tail = NULL,
        .num_items = 8, // 初始商品个数为8
        .lock = PTHREAD_MUTEX_INITIALIZER,
        .not_full = PTHREAD_COND_INITIALIZER,
        .not_empty = PTHREAD_COND_INITIALIZER
    };

    pthread_t producer_threads[PRODUCER_NUM];
    pthread_t consumer_threads[CONSUMER_NUM];

    for (int i = 0; i < PRODUCER_NUM; i++) {
        pthread_create(&producer_threads[i], NULL, producer, &q);
    }

    for (int i = 0; i < CONSUMER_NUM; i++) {
        pthread_create(&consumer_threads[i], NULL, consumer, &q);
    }

    for (int i = 0; i < PRODUCER_NUM; i++) {
        pthread_join(producer_threads[i], NULL);
    }

    for (int i = 0; i < CONSUMER_NUM; i++) {
        pthread_join(consumer_threads[i], NULL);
    }

    return 0;
}

代码中使用了一个结构体 queue 来描述商品队列,其中包含了队列头和尾指针、当前队列中商品个数、互斥锁和两个条件变量。生产者线程的主要逻辑是每隔3秒产生一个商品,如果队列已满就等待条件变量 not_full,否则将新的商品加入队列,并发送条件变量 not_empty 通知消费者线程,最后释放互斥锁。消费者线程的主要逻辑是每隔1秒消耗一个商品,如果队列为空就等待条件变量 not_empty,否则从队列头取出一个商品并释放相应的内存,然后发送条件变量 not_full 通知生产者线程,最后释放互斥锁。

需要注意的是,由于生产者和消费者线程访问队列需要互斥,所以需要使用互斥锁 lock 来保护队列。同时,每个条件变量 not_fullnot_empty 对应一个互斥锁,这是因为条件变量的等待和发送操作必须在互斥锁的保护下进行,否则可能出现竞态条件。在代码中,等待条件变量的操作使用了 pthread_cond_wait 函数,它会自动释放互斥锁并进入等待状态,直到被相应的条件变量发送通知并重新获得互斥锁。发送条件变量的操作使用了 pthread_cond_signal 函数,它会唤醒一个等待该条件变量的线程,如果有多个等待线程,只有其中一个会被唤醒,其他线程继续等待。

现在你是linux专家请用C语言完成以下题目:使用条件变量实现生产者-消费者问题 1商品使用一个链式队列描述初始商品个数为8最大商品个数是10个不同的商品用不同的随机数区分 2生产者有3个线程每个线程每3秒产生一个商品 3 消费者有2个线程先睡眠5秒每个线程每1秒消耗一个商品 显示每次生产和消费的商品的随机编号。

原文地址: http://www.cveoy.top/t/topic/bvWS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录