Производители Потребители Нитки и Мьютекс - PullRequest
0 голосов
/ 20 февраля 2019

Относительно того, когда производитель обращается к общему источнику, нужна ли мне другая переменная условия / сигнал условия?Так что он блокируется, когда общий ресурс заблокирован.У меня есть переменная условия для потребителя, так что он ждет, и если он не будет пытаться получить доступ, если там нечего добавить (потреблять)

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 голосов
/ 22 февраля 2019

Условная переменная - это способ эффективной блокировки потока до тех пор, пока не будет проверено определенное условие.

Вы используете условную переменную в потребителе просто потому, что диктуете, что не может потреблять, если нетНичего не потребляет - поэтому вы решаете заблокировать, пока не будет чего-то потреблять.В вашем случае это происходит, когда toConsume == 0.

. Вы можете диктовать, что производитель также должен ждать - это полностью соответствует вашей спецификации.Некоторые идеи:

  • Возможно, вы захотите запретить переменной превышать определенное значение (например, 1000 или INT_MAX, чтобы избежать переполнения).
  • Если вместоЕсли вы используете круговой буфер для размещения ваших вещей для использования, производитель должен подождать, если нет свободных слотов для размещения вещей в буфере.Это самый распространенный способ обучения производителей-потребителей в учебниках:)
...