如何修复生产者-消费者程序,以便当计数器达到 10 时两个线程都终止?

问题描述 投票:0回答:1

我正在尝试用 C 语言编写一个小程序,实现两个线程的生产者-消费者方法。我打算让它共享一个互斥体和两个条件变量,以使计数变量从 0 计数到 10。我现在遇到的一些问题,因为在向程序发送消息后它仍在运行消费者线程end 当后者需要作为输出的最后一行时。我已经记录了需要使用的线程,但是我该如何解决这里发生的问题?

当前代码:

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

#define SIZE 10
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t myCond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t myCond2 = PTHREAD_COND_INITIALIZER;
int myCount = 0;

void print_mutex_status(const char* thread, const char* status) {
    printf("%s: myMutex %s\n", thread, status);
}

void print_cond_status(const char* thread, const char* cond) {
    printf("%s: %s\n", thread, cond);
}

void* producer_thread(void* arg) {
    while (1) {
        pthread_mutex_lock(&myMutex);
        print_mutex_status("PRODUCER", "locked");
        while (myCount == SIZE) {
            print_cond_status("PRODUCER", "waiting on myCond1");
            pthread_cond_wait(&myCond1, &myMutex);
        }
        // Produce an item
        printf("myCount: %d -> %d\n", myCount, myCount + 1);
        myCount++;
        pthread_mutex_unlock(&myMutex);
        print_mutex_status("PRODUCER", "unlocked");
        pthread_cond_signal(&myCond2);
        print_cond_status("PRODUCER", "signaling myCond2");
        if (myCount == SIZE) {
            printf("PROGRAM END\n");
            exit(EXIT_SUCCESS); // Corrected line to terminate the program
        }
    }
    return NULL;
}

void* consumer_thread(void* arg) {
    while (1) {
        pthread_mutex_lock(&myMutex);
        print_mutex_status("CONSUMER", "locked");
        while (myCount == 0) {
            print_cond_status("CONSUMER", "waiting on myCond2");
            pthread_cond_wait(&myCond2, &myMutex);
        }
        // Consume an item
        printf("myCount: %d -> %d\n", myCount, myCount - 1);
        myCount--;
        pthread_mutex_unlock(&myMutex);
        print_mutex_status("CONSUMER", "unlocked");
        pthread_cond_signal(&myCond1);
        print_cond_status("CONSUMER", "signaling myCond1");
    }

    return NULL;
}

int main() {
    printf("PROGRAM START\n");
    pthread_t producer, consumer;
    if (pthread_create(&producer, NULL, producer_thread, NULL) != 0) {
        perror("Error creating producer thread");
        exit(EXIT_FAILURE);
    }
    if (pthread_create(&consumer, NULL, consumer_thread, NULL) != 0) {
        perror("Error creating consumer thread");
        exit(EXIT_FAILURE);
    }
    printf("CONSUMER THREAD CREATED\n");
    pthread_join(producer, NULL);
    pthread_mutex_destroy(&myMutex);
    pthread_cond_destroy(&myCond1);
    pthread_cond_destroy(&myCond2);
    return 0;
}

示例输出(实际上贯穿多行,我无法放在这里......

myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
CONSUMER: signaling myCond1
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
CONSUMER: myMutex locked
myCount: 1 -> 0
CONSUMER: myMutex unlocked
PRODUCER: myMutex locked
myCount: 0 -> 1
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 1 -> 2
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 2 -> 3
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 3 -> 4
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 4 -> 5
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 5 -> 6
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 6 -> 7
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 7 -> 8
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 8 -> 9
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PRODUCER: myMutex locked
myCount: 9 -> 10
PRODUCER: myMutex unlocked
PRODUCER: signaling myCond2
PROGRAM END
CONSUMER: signaling myCond1
CONSUMER: signaling myCond1
CONSUMER: myMutex locked

一旦程序开始,一行应该写着“PROGRAM START”,这已经很难找到了。此外,消费者线程需要在第二次增量之前创建,这又很难找到。另外,“PROGRAM END”应该是最后一行,而不是倒数第四行。

c multithreading operating-system
1个回答
0
投票

您的代码中存在一些问题。

当生产者打印“PROGRAM END”时,消费者线程仍在运行,因此它可以在打印“PROGRAM END”后打印消息。如果希望“PROGRAM END”成为最后打印的消息,则必须确保在打印“PROGRAM END”之前停止消费者线程。换句话说 - 您需要首先在消费者线程上执行

pthread_join

这会导致另一个问题。当前消费者线程无法结束。代码中没有退出条件。你需要补充一下。

我可能会将“PROGRAM END”的打印移至

main
,而不是在生产者线程中进行。
main
中类似的东西:

pthread_join(producer, NULL);
pthread_join(consumer, NULL);
printf("PROGRAM END\n");

在生产者线程中,您遇到了问题:

if (myCount == SIZE) {

这里您无需锁即可访问共享变量。

© www.soinside.com 2019 - 2024. All rights reserved.