【发布时间】:2014-07-26 12:39:06
【问题描述】:
#include <stdio.h>
#include <pthread.h>
#define MAX 10 /* maximum iterations */
int number; /* the resource */
pthread_mutex_t mu= PTHREAD_MUTEX_INITIALIZER; /* to protect the resource*/
/*
Condition variable to signal consumer that a new number is available for
consumption.
*/
pthread_cond_t sig_consumer= PTHREAD_COND_INITIALIZER;
/*
Condition variable to signal the producer that
(a) the new number has been consumed,
(b) generate another one.
*/
pthread_cond_t sig_producer= PTHREAD_COND_INITIALIZER;
void *consumer(void *dummy)
{
int printed= 0;
printf("Consumer : \"Hello I am consumer #%ld. Ready to consume numbers"
" now\"\n", pthread_self());
while (1)
{
pthread_mutex_lock(&mu);
/* Signal the producer that the consumer is ready. */
pthread_cond_signal(&sig_producer);
/* Wait for a new number. */
pthread_cond_wait(&sig_consumer, &mu);
/* Consume (print) the number. */
printf("Consumer : %d\n", number);
/* Unlock the mutex. */
pthread_mutex_unlock(&mu);
/*
If the MAX number was the last consumed number, the consumer should
stop.
*/
if (number == MAX)
{
printf("Consumer done.. !!\n");
break;
}
}
}
/**
@func producer
This function is responsible for incrementing the number and signalling the
consumer.
*/
void *producer(void *dummy)
{
printf("Producer : \"Hello I am producer #%ld. Ready to produce numbers"
" now\"\n", pthread_self());
while (1)
{
pthread_mutex_lock(&mu);
number ++;
printf("Producer : %d\n", number);
/*
Signal the consumer that a new number has been generated for its
consumption.
*/
pthread_cond_signal(&sig_consumer);
/*
Now wait for consumer to confirm. Note, expect no confirmation for
consumption of MAX from consumer.
*/
if (number != MAX)
pthread_cond_wait(&sig_producer, &mu);
/* Unlock the mutex. */
pthread_mutex_unlock(&mu);
/* Stop if MAX has been produced. */
if (number == MAX)
{
printf("Producer done.. !!\n");
break;
}
}
}
void main()
{
int rc, i;
pthread_t t[2];
number= 0;
/* Create consumer & producer threads. */
if ((rc= pthread_create(&t[0], NULL, consumer, NULL)))
printf("Error creating the consumer thread..\n");
if ((rc= pthread_create(&t[1], NULL, producer, NULL)))
printf("Error creating the producer thread..\n");
/* Wait for consumer/producer to exit. */
for (i= 0; i < 2; i ++)
pthread_join(t[i], NULL);
printf("Done..\n");
}
问题:如果消费者线程在生产者线程之前启动,那么程序会提供预期的结果,但是如果生产者先启动,那么消费者将从第2个开始消费;消费者无法消费1号。如何在生产者线程先启动的情况下纠正程序,而不引入任何额外的变量或睡眠?
【问题讨论】:
-
这不是你使用
pthread_cond_wait的方式。您需要在循环中调用它(它可能会自发返回),并且每次循环都需要测试,在锁定的情况下,您实际上是否能够继续。 -
请注意,当您使用 POSIX 线程时,
void main()是不允许的。它只在 Windows 系统上是允许的,即使在那里也是一种异常(但有记录的异常)。 -
@AlanStokes,您的示例包含另外一个名为 enum { STATE_A, STATE_B } state = STATE_A; 的全局变量。我的意图是没有任何额外的变量如何克服我的问题。
-
你不能。该问题的答案以及下面的答案解释了这一点。