【问题标题】:Thread main with 2 sons thread to loop x times product & consumer带有 2 个子线程的主线程循环 x 次产品和消费者
【发布时间】:2019-03-09 04:38:45
【问题描述】:

我编写了一个程序,其中主线程创建了 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);
}

【问题讨论】:

    标签: c pthreads mutex semaphore


    【解决方案1】:

    你可以通过一些修改做你想做的事:

    • 使用两个而不是一个信号量:一个信号量告诉消费者一个 number 已准备就绪,用于告诉生产者消费者已准备好消费。
    • 有一个特殊值向消费者表明生产者不会 不再生产了。

    所以,你可以这样改变你的代码:

    信号量声明

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2018-03-08
        • 2013-12-20
        • 1970-01-01
        • 1970-01-01
        • 2018-07-09
        • 1970-01-01
        • 1970-01-01
        • 2018-09-24
        • 2017-02-01
        相关资源
        最近更新 更多