具有2个子线程的主线程循环x次乘积和消费者

时间:2018-10-03 21:03:25

标签: c pthreads mutex semaphore

我编写了一个程序,其中线程main创建了2个子线程。等待一个随机时间,然后产生一个1到6之间的随机值,并将该值放入randomValue变量中。另一个等待并读取全局变量randomValue并打印该变量。因此,我使用一个信号量来确保读取的线程将始终读取另一个线程写入的值。

我想进行修改,以便每个线程都不知道x循环(2,3 ...),以便它可以产生x倍的随机值,并将该值放入randomValue,另一个线程将读取x乘以randomValue变量并将其打印出来。任何修改代码的想法都值得欢迎。非常感谢。

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>

/* variable shared by producer and consumer 
 (producer writes a value between 1 and 6) */

long randomValue = 0;
/**semaphore  **/
sem_t mex;


// function that create a random sleep-time (to induce unpredictability)
static int duration(int min, int max)
{
  static int first_time = 1;

  // Seed the random number generator with the current time
  // of day if we haven't done so yet.
  if (first_time) {
    first_time = 0;
    srand48((int) time(NULL));
  }
  return (int) (min + drand48()*(max - min));
}

/* producer program */
void *producer(void *arg) {
  char statearray[256];

  // Initialize random generator
  // Note that initstate and random are not threadsafe
  initstate(time(NULL), statearray, 256);

   sleep(duration(1,3));
   printf("prod: producing ...\n");
//random value 1 et 6
   randomValue = random();
   randomValue = ((double) randomValue / RAND_MAX)*6+1;
//put the value
   printf("prod: delivering  %ld\n", randomValue);
   sem_post(&mex); 
  pthread_exit(NULL);
}

/* consumer program */
void *consumer(void *arg) {


  sleep(duration(1,5));
  sem_wait(&mex);
  printf("cons: consuming ...\n");
  // 

  printf("cons: received %ld\n", randomValue);


  pthread_exit(NULL);
}

/* main thread */
int main(int argc, char *argv[]) {
  pthread_t tidprod, tidcons;


    if (sem_init(&mex,0,0)  != 0){
    perror("sem_init");
    exit(EXIT_FAILURE);
   }

  if (pthread_create(&tidprod, NULL, producer, NULL) != 0) {
    perror("pthread_create");
  }
  if (pthread_create(&tidcons, NULL, consumer, NULL) != 0) {
    perror("pthread_create");
  }


  if (pthread_join(tidcons, NULL) != 0) {
    perror("pthread_join prod");
  }

  if (pthread_join(tidprod, NULL) != 0) {
    perror("pthread_join prod");
  }

  fflush(stdout);
  pthread_exit(EXIT_SUCCESS);
}

2 个答案:

答案 0 :(得分:1)

如果只想发送和接收多个值,则不太清楚。

要发送和接收多个值,请在生产者和使用者中使用for循环,并使用一个数组作为randomValue。如果要产生一个值并首先使用它,则循环将包括“ sem_post(&mex);”。在生产者和“ sem_wait(&mex);”中在循环。否则,sem_post()和sem_wait()将在循环之外。

答案 1 :(得分:1)

您可以做一些修改就可以做:

  • 代替两个信号灯,而使用两个:一个信号灯告诉消费者 数字已经准备好了,告诉生产者消费者已经准备好消费了。
  • 具有特殊值,可以向消费者表明生产者不会 再生产了。

因此,您可以通过以下方式更改代码:

信号量声明

/*semaphores  */
/* Set by producer when production is ready */
sem_t mex_prod;
/* Set by consumer when ready to consume */
sem_t mex_cons;

信号量初始化

/* 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);
}