c - Thread main with 2 sons thread循环x次产品和消费者

标签 c pthreads mutex semaphore

我编写了一个程序,其中主线程创建了 2 个子线程。等待一段随机时间,然后生成一个介于 1 和 6 之间的随机值,并将该值放入 randomValue 变量中。另一个等待并读取全局变量 randomValue 并打印变量。所以我使用单个信号量来确保读取的线程将始终读取另一个线程写入的值。

我想修改让每个线程都不知道 x loops( 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);
}

最佳答案

你可以做一些你想做的事:

  • 使用两个代替一个信号量:一个信号量告诉消费者 number is ready, 一个告诉生产者消费者已经准备好消费了。
  • 有一个特殊的值(value)来向消费者表明生产者不会 不再生产。

因此,您可以这样更改代码:

信号量声明

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

关于c - Thread main with 2 sons thread循环x次产品和消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52635670/

相关文章:

c - openGL glDrawPixels

c - 在 C 代码中静态链接 libclang

c++ - 从包装函数调用时 pthread_create 什么都不做

c++ - 事件/任务队列多线程 C++

c - pthread_mutex_lock 卡住了

c - 在 C 中实现互斥体的问题

C# - 如何获得互斥量的所有者名称

c - do While 循环不适用于 C 中的字符串比较

c - 关于指针和结构体的代码中的问题

c - pthread 完成后打印变量