まず、念のため、ある意味でpthread_cond_signal
を送信しないでください。条件変数にフラグを立て、それを待機している変数を解放するだけです。したがって、消費プロセスがうまく呼び出す前に呼び出すと、それは無視されます。signal
signal(2)
pthread_cond_signal
次に、pthread_cond_waitは高速ですか、それとも低速ですか?まあ、それは異なります。使い勝手が悪く、上手く使えます。あなたがそれをうまく使わなければ、私はそれがひどく機能すると確信しています。実際に必要なときにだけ待つと、うまく機能すると思います。
したがって、条件変数を使用するにはミューテックスを保持する必要があるため、この時点でデータがあるかどうかを確認することをお勧めします(そして、このミューテックスを同期ポイントとして使用します)。
キューデータ構造のアイデア:
struct q {
struct qe *h;
struct qe *t;
pthread_mutex_t m;
pthread_cond_t c;
int len;
};
コンシューマー(ヘッドチェックの周りをロックする必要がある複数のコンシューマーがある場合は、コンシューマーが1つだけであると想定):
void *consumer(void*arg) {
struct q *q = arg;
while(1) {
pthread_mutex_lock(&q->m);
if(q->h == NULL)
pthread_cond_wait(&q->c, &q->m);
/* We hold the mutex when we exit pthread_cond_wait */
pthread_mutex_unlock(&q->m); /* we can make the check without the mutex */
while(q->h != NULL) {
pthread_mutex_lock(&q->m); /* but we need it to modify */
pop();
pthread_mutex_unlock(&q->m);
/* Process data */
}
}
}
プロデューサー:
void *producer(void*arg) {
int i;
struct q *q = arg;
while(1) {
pthread_mutex_lock(&q->m);
push(q, some_data);
if(q->h == q->t) /* only one element */
pthread_cond_signal(&q->c);
pthread_mutex_unlock(&q->m);
}
return NULL;
}