生产者消费者线程和互斥量

时间:2019-02-20 14:20:32

标签: c multithreading pthreads mutex

关于生产者何时访问共享源,我是否需要另一个条件变量/条件信号?因此,当共享资源被锁定时,它确实会被阻止。我有一个供消费者使用的条件变量,因此它会等待,如果没有东西可以添加(消费),它将不会尝试访问

int pnum;  // number updated when producer runs.
int csum;  // sum computed using pnum when consumer runs.

int (*pred)(int); // predicate indicating number to be consumed
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t condc,condp;

int toConsume = 0; // condition varibale counter
int produceT() {
    //Start Critical Section
    pthread_mutex_lock(&mutex);
    scanf("%d",&pnum);
    toConsume++;
    //End Critical Section
    pthread_cond_signal (&condc);

    pthread_mutex_unlock(&mutex);
    return pnum;
}

void *Produce(void *a) {
  int p;

  p=1;
  while (p) {
    printf("producer thinking...\n");
    sleep(1);
    printf("..done!\n");
    p = produceT();
    printf("PRODUCED %d\n",p);
  }
  printf("EXIT-P\n");
  pthread_exit(0);
}


int consumeT() {
    pthread_mutex_lock(&mutex); //protect buffer
    while(toConsume <=0){ // if nothing in buffer then wait
        pthread_cond_wait(&condc,&mutex);
    }
    pthread_mutex_unlock(&mutex); //release buffer
    //sleep()
    pthread_mutex_lock(&mutex); //protect buffer
    if ( pred(pnum) ) { csum += pnum; }
    toConsume--;
    pthread_mutex_unlock(&mutex);
    return pnum;
}

void *Consume(void *a) {
  int p;

  p=1;
  while (p) {
    printf("consumer thinking...\n");
    sleep(rand()%3);
    printf("..done!\n");
    p = consumeT();
    printf("CONSUMED %d\n",csum);
  }
  printf("EXIT-C\n");
  pthread_exit(0);
}


int main (int argc, const char * argv[]) {
  // the current number predicate
  static pthread_t prod,cons;
    long rc;

  pred = &cond1;
  if (argc>1) {
    if      (!strncmp(argv[1],"2",10)) { pred = &cond2; }
    else if (!strncmp(argv[1],"3",10)) { pred = &cond3; }
  }
  pthread_mutex_init(&mutex,NULL);
  pthread_cond_init(&condc,NULL);//Initialize consumer condition variable
  pthread_cond_init(&condp,NULL);//Initialize producer condition variable

  pnum = 999;
  csum=0;
  srand(time(0));

  printf("Creating Producer:\n");
    rc = pthread_create(&prod,NULL,Produce,(void *)0);
    if (rc) {
            printf("ERROR return code from pthread_create(prod): %ld\n",rc);
            exit(-1);
        }
  printf("Creating Consumer:\n");
    rc = pthread_create(&cons,NULL,Consume,(void *)0);
    if (rc) {
            printf("ERROR return code from pthread_create(cons): %ld\n",rc);
            exit(-1);
        }

    pthread_join( prod, NULL);
    pthread_join( cons, NULL);


  printf("csum=%d.\n",csum);

  return 0;
}

1 个答案:

答案 0 :(得分:0)

条件变量是一种有效地阻塞线程直到验证特定条件的方法。

您在使用者中使用条件变量仅仅是因为您指示您如果没有要消费的东西就不能消费-因此,您决定阻塞直到有要消费的东西。就您而言,这是在PUBLIC_URL时发生的。

您可能会要求生产者也必须等待-这完全取决于您的规范。一些想法:

  • 您可能希望阻止变量超过某个值(例如toConsume == 01000以避免溢出)。
  • 如果您使用circular buffer而不是柜台来放置您的事物,则生产者必须等待,如果没有空闲的插槽来放置事物在缓冲区中。这是教教科书中的生产者-消费者的最常见方法:)