我的作业提供了运行时使用大量 CPU 的代码。目标是通过在生产者消费者问题中实施条件变量来减少该数量。
我按照我最好的理解提供的说明进行操作,在互斥体解锁之前在生产者端添加 wait() 函数,然后从 if-else 语句的 else 部分发送信号。
// if buffer is full, release mutex lock and check again
if (shared_count == NITEMS){
// wait when full
pthread_cond_wait(&cond1, &mutex);
pthread_mutex_unlock(&mutex);
}
else{
//signal
pthread_cond_signal(&cond1);
break;
}
我在消费者方面也做了同样的事情。
问题是我的整体代码不再提供任何输出。
我在下面包含了完整的代码,以防有帮助
/* minor3.c - using producer-consumer paradigm. */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NITEMS 10 // number of items in shared buffer
// shared variables
char shared_buffer[NITEMS]; // echo buffer
int shared_count; // item count
pthread_mutex_t mutex; // pthread mutex
unsigned int prod_index = 0; // producer index into shared buffer
unsigned int cons_index = 0; // consumer index into shard buffer
// function prototypes
void * producer(void *arg);
void * consumer(void *arg);
// Consumer variables
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
int main()
{
pthread_t prod_tid, cons_tid1, cons_tid2;
// initialize pthread variables
pthread_mutex_init(&mutex, NULL);
// initialize condition variables
pthread_cond_init(&cond1, NULL);
pthread_cond_init(&cond2, NULL);
// start producer thread
pthread_create(&prod_tid, NULL, producer, NULL);
// start consumer threads
pthread_create(&cons_tid1, NULL, consumer, NULL);
pthread_create(&cons_tid2, NULL, consumer, NULL);
// wait for threads to finish
pthread_join(prod_tid, NULL);
pthread_join(cons_tid1, NULL);
pthread_join(cons_tid2, NULL);
// clean up
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
return 0;
}
// producer thread executes this function
void * producer(void *arg)
{
char key;
printf("Enter text for producer to read and consumer to print, use Ctrl-C to exit.\n\n");
// this loop has the producer read data in from stdin and place the read data on the shared buffer
while (1)
{
// read input key
scanf("%c", &key);
// this loop is used to poll the shared buffer to see if it is full:
// -- if full, unlock and loop again to keep polling
// -- if not full, keep locked and proceed to place character on shared buffer
while (1)
{
// acquire mutex lock
pthread_mutex_lock(&mutex);
// if buffer is full, release mutex lock and check again
if (shared_count == NITEMS){
// wait when full
pthread_cond_wait(&cond1, &mutex);
pthread_mutex_unlock(&mutex);
}
else{
//signal
pthread_cond_signal(&cond1);
break;
}
}
// store key in shared buffer
shared_buffer[prod_index] = key;
// update shared count variable
shared_count++;
// update producer index
if (prod_index == NITEMS - 1)
prod_index = 0;
else
prod_index++;
// release mutex lock
pthread_mutex_unlock(&mutex);
}
return NULL;
}
// consumer thread executes this function
void * consumer(void *arg)
{
char key;
long unsigned int id = (long unsigned int)pthread_self();
// this loop has the consumer get data from the shared buffer and print to stdout
while (1)
{
// this loop is used to poll the shared buffer to see if it is empty:
// -- if empty, unlock and loop again to keep polling
// -- if not empty, keep locked and proceed to get character from shared buffer
while (1)
{
// acquire mutex lock
pthread_mutex_lock(&mutex);
// if buffer is empty, release mutex lock and check again
if (shared_count == 0){
pthread_cond_wait(&cond2, &mutex);
pthread_mutex_unlock(&mutex);
}
else{
pthread_cond_signal(&cond2);
break;
}
}
// read key from shared buffer
key = shared_buffer[cons_index];
// echo key
printf("consumer %lu: %c\n", (long unsigned int) id, key);
// update shared count variable
shared_count--;
// update consumer index
if (cons_index == NITEMS - 1)
cons_index = 0;
else
cons_index++;
// release mutex lock
pthread_mutex_unlock(&mutex);
}
return NULL;
}
你有两个错误。
首先,你永远不会将
shared_count
设置为零。您可以递增、递减并测试它。但你永远不会初始化它。
其次,消费者发出消费者等待的条件变量信号,反之亦然。您需要消费者向生产者发出信号,反之亦然!
最后,虽然这不是一个错误,但您的循环不必要地解锁互斥体,只是为了在下一次迭代时立即再次锁定它。在内循环之外解锁互斥体可能更有意义。