2016-04-19 10 views
0

私は、pthreadsとセマフォを使ってCのプロデューサ/コンシューマの問題を解決しました。遅いpthreadコンシューマ

私のメインスレッドはプロデューサーであり、私はN個のコンシューマースレッドを起動します。

私のコードは次のとおりです。

typedef struct 
{ 
    int buf[BUFSIZE];  /* shared var */ 
    int in;    /* buf[in%BUFSIZE] is the first empty slot */ 
    int out;    /* buf[out%BUFSIZE] is the first full slot */ 
    sem_t full;   /* keep track of the number of full spots */ 
    sem_t empty;   /* keep track of the number of empty spots */ 
    pthread_mutex_t mutex;   /* enforce mutual exclusion to shared data */ 
} CONSUMER_STRUCT; 

CONSUMER_STRUCT shared; 

これは私の消費者のスレッドのそれぞれのコードです:

void *Consumer(void *arg) 
{ 
    int fd, workerID, i, hit=0; 

    workerID = *(int *)arg; 

    for (;;) { 
     sem_wait(&shared.full); 
     pthread_mutex_lock(&shared.mutex); 
     fd = shared.buf[shared.out]; 
     printf("\n[C%d] Consumed. I got %d ...Valor do buffer: %d na posição %d\n\n\n", workerID, fd, shared.buf[shared.out], shared.out); 
     ftp(fd, hit); 
     shared.buf[shared.out] = 0; 
     shared.out = (shared.out+1)%BUFSIZE; 
     fflush(stdout); 
     printf("\n\n\n\nEstado do buffer:\n\n\n\n"); 
     for (i = 0; i < BUFSIZE; i++) { 
      //printf("%d ", shared.buf[i]); 
     } 
     /* Release the buffer */ 
     pthread_mutex_unlock(&shared.mutex); 
     /* Increment the number of full slots */ 
     sem_post(&shared.empty); 
     hit++; 
    } 
    return NULL; 
} 

そして、これが私のプロデューサースレッドのコードです:

item = socketfd; 

sem_wait(&shared.empty); 
pthread_mutex_lock(&shared.mutex); 

shared.buf[shared.in] = item; 

shared.in = (shared.in + 1) % BUFSIZE; 
fflush(stdout); 

pthread_mutex_unlock(&shared.mutex); 
sem_post(&shared.full); 

すべて正常に動作していますが、22ファイルには約20秒かかりますが、要求ごとに1スレッドを作成するには2秒!これは一度にスレッドを実行しているようだが、私はそれらをすべて同時に実行したい。

私の実装アプローチに何か間違っていますか?

+1

消費者は効果的にその操作全体の中でミューテックスを保持しています。同期オーバーヘッドでシングルスレッドを実行しています。 – EOF

+0

私はあなたが何を意味したのか理解しました!この問題に対する正しいアプローチは何でしょうか? – rafaelcpalmeida

+2

Consumer()の 'ftp()'が消費者の実行時間を支配しているとしましょう。さらに、 'ftp()'がスレッドセーフであるとしましょう。次に、 'pthread_mutex_unlock()'の下で 'ftp()'を動かして、実際に同時に実行することができます。 – EOF

答えて

0

似たような問題が発生した場合は、こちらをご覧ください。

@Martin Jamesと@EOFのおかげです。

void *Consumer(void *arg) 
{ 
    int fd, workerID, i, hit=0; 

    workerID = *(int *)arg; 

    for (;;) { 
     sem_wait(&shared.full); 
     pthread_mutex_lock(&shared.mutex); 
     fd = shared.buf[shared.out]; 
     shared.buf[shared.out] = 0; 
     shared.out = (shared.out+1)%BUFSIZE; 
     pthread_mutex_unlock(&shared.mutex); 
     printf("\n[C%d] Consumed. I got %d ...Valor do buffer: %d na posição %d\n\n\n", workerID, fd, shared.buf[shared.out], shared.out); 
     ftp(fd, hit); 
     fflush(stdout); 
     printf("\n\n\n\nEstado do buffer:\n\n\n\n"); 
     for (i = 0; i < BUFSIZE; i++) { 
      //printf("%d ", shared.buf[i]); 
     } 
     /* Release the buffer */ 
     /* Increment the number of full slots */ 
     sem_post(&shared.empty); 
     hit++; 
    } 
    return NULL; 
} 

問題は、私は、ミューテックスをロックする機能を実行した後、ミューテックスのロックを解除したことです。これは、実行に多くの遅延を引き起こしていたものです。