2016-12-27 6 views
0

pthreadとセマフォを使用して簡単なプロデューサコンシューマを作成しました。私は時々アウト・オブ・オーダー(生産者が生産する前に消費する消費者)のアウトプットを時々得ている。問題を見つけるのを手伝ってください。私はさまざまなソースとチュートリアルを使ってロジックを検証しましたが、依然として望ましくない結果を得ています。pthreadsとセマフォを使用するプロデューサコンシューマの同期エラー

#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は非通知emaphoresをサポートしていません。名前付きセマフォだけをサポートします。だから私のコードで無名のセマフォを使用する代わりに、私はコードを動作させるために名前付きセマフォと置き換える必要がありました。 OSXはpthreadsのサポートが非常に貧弱です。また、pthread障壁をサポートしていません。 私はセマフォのinit行を次のように置き換える必要がありました。

  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 
関連する問題