2016-12-27 5 views
0

pthread 및 세마포를 사용하여 간단한 제작자 소비자를 작성했습니다. 나는 때때로 (생산자가 생산하기 전에 소비하는 소비자) 출력이 나 빠지고있다. 문제를 찾는데 도와주세요. 다양한 소스 및 자습서를 사용하여 로직을 검증했지만 여전히 원하지 않는 결과를 얻었습니다.pthread 및 세마포를 사용하는 제작자 소비자의 동기화 오류

#include <iostream> 
    #include <pthread.h> 
    #include <semaphore.h> 
    #include <string> 
    #include <sstream> 
    #include <unistd.h> 
    #include "pthread_barrier.hpp" 

    sem_t empty; 
    sem_t full; 
    sem_t lock; 
    pthread_mutex_t wlock; 

    pthread_barrier_t pbarrier; 
    pthread_barrier_t cbarrier; 

    pthread_attr_t tattr; 

    #define BUFF_SIZE 100 

    volatile bool buffer[BUFF_SIZE]; 
    int prodIterator = 0; 
    int consIterator = 0; 

    void *Producer(void *args) 
    { 
     pthread_barrier_wait(&pbarrier); 
     while(1) { 
      sem_wait(&empty); 
      sem_wait(&lock); 
      buffer[prodIterator] = true; 
      pthread_mutex_lock(&wlock); 
      std::stringstream str; 
      std::cout<<"producer produced = "<<prodIterator<<"\n"; 
      pthread_mutex_unlock(&wlock); 
      prodIterator = (++prodIterator)% BUFF_SIZE; 
      sem_post(&lock); 
      sem_post(&full); 
      sleep(1); 
     } 
    } 

    void *Consumer(void *args) 
    { 
     pthread_barrier_wait(&cbarrier); 
     while(1) { 
      sem_wait(&full); 
      sem_wait(&lock); 
      buffer[consIterator] = false; 
      pthread_mutex_lock(&wlock); 
      std::cout<<"Consumer consumed = "<<consIterator<<"\n"; 
      pthread_mutex_unlock(&wlock); 
      consIterator = (++consIterator)% BUFF_SIZE; 
      sem_post(&lock); 
      sem_post(&empty); 
      sleep(1); 
     } 
    } 


    int main() 
    { 
     sem_init(&empty, 0, BUFF_SIZE); 
     sem_init(&full, 0, 0); 
     sem_init(&lock, 0, 1); 

     pthread_mutex_init(&wlock, NULL); 

     pthread_t prod[10]; 
     pthread_t cons[10]; 

     unsigned pcount = 5; 
     unsigned ccount = 2; 
     pthread_barrier_init(&pbarrier, NULL, pcount); 
     pthread_barrier_init(&cbarrier, NULL, ccount); 

     pthread_attr_init(&tattr); 
     pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 

     for(int i=0;i<5;i++) { 
      pthread_create(&prod[i], &tattr, Producer, NULL); 
     } 

     for(int i=0;i<2;i++) { 
      pthread_create(&cons[i], &tattr, Consumer, NULL); 
     } 

     pthread_exit(NULL); 
    } 
+1

무엇이 pthread_barrier입니까? – zoska

+0

pthread_barrier는 특정 수의 스레드가 pthread_barrier_wait api에 도달 할 때까지 스레드가 실행되는 것을 중지하기위한 것입니다. 진정한 경쟁 조건 및 멀티 스레딩 환경을 만들기위한 것입니다. – Dheeraj

답변

0

나는이 문제를 발견했다. 나는 mac osx를 사용하고 있으며 mac osx는 unnemed emaphores를 지원하지 않습니다. 명명 된 세마포어 만 지원합니다. 따라서 코드에서 무명 세마포어를 사용하는 대신 코드 작업을 위해 이름이 지정된 세마포어로 바꿔야했습니다. OSX는 pthreads에 대한 지원이 매우 부족합니다. 또한 pthread 장벽을 지원하지 않습니다. 그래서 세마포어 초기화 라인을 다음과 같이 바꿔야합니다 :

  full = sem_open("/semaphore1", O_CREAT, 0777, 1); 
      empty = sem_open("/semaphore2", O_CREAT, 0777, 1); 
      lock = sem_open("/semaphore3", O_CREAT, 0777, 1); 

      and the declaration of semaphore variables needed be replace by : 

      sem_t *empty; 
      sem_t *full; 
      sem_t *lock; 

      very poor support indeed for pthreads in mac osx