Вы можете делать то, что хотите, с помощью нескольких модификаций:
- Вместо одного семафора используйте два: один семафор, чтобы сообщить потребителю, что число готово, другой, чтобы сообщить производителю, что потребительготов к употреблению.
- Имеет специальное значение, указывающее потребителю, что производитель больше не будет производить.
Итак, вы можете изменить свой код следующим образом:
Объявление семафоров
/*semaphores */
/* Set by producer when production is ready */
sem_t mex_prod;
/* Set by consumer when ready to consume */
sem_t mex_cons;
Семафоры init
/* by default, nothing produced */
if (sem_init(&mex_prod,0,0) != 0){
perror("sem_init");
exit(EXIT_FAILURE);
}
/* by default, consumer is not ready */
if (sem_init(&mex_cons,0,0) != 0){
perror("sem_init");
exit(EXIT_FAILURE);
}
функция потока производителя
(я удалил ваш комментарий)
void *producer(void *arg) {
char statearray[256];
initstate(time(NULL), statearray, 256);
/* choose how much to product */
int number_of_productions = 2 + random()%5;
printf("prod: %d to produce\n", number_of_productions );
/* this loop can be replaced by some for (i = 0; i< num; ++i) loop */
while(number_of_productions--)
{
sleep(duration(1,3));
/* wait for consumer to be ready */
sem_wait(&mex_cons);
printf("prod: producing ...\n");
randomValue = random();
randomValue = ((double) randomValue / RAND_MAX)*6+1;
printf("prod: delivering %ld\n", randomValue);
sem_post(&mex_prod);
}
sem_wait(&mex_cons);
/* generate a special value to tell the consumer that no new value
will be given */
randomValue = -1;
sem_post(&mex_prod);
pthread_exit(NULL);
}
функция пользовательских потоков
void *consumer(void *arg) {
/* tell producer that consumer is ready */
sem_post(&mex_cons);
/* since we don't know how many value will be generated, we have an
infinite loop */
while(1)
{
sleep(duration(1,5));
sem_wait(&mex_prod);
printf("cons: consuming ...\n");
printf("cons: received %ld\n", randomValue);
/* value has been consumed, tell producer we are ready for a new one */
sem_post(&mex_cons);
/* if randomValue is -1, we break the loop since no more value will come */
if (-1 == randomValue)
break;
}
pthread_exit(NULL);
}