0

私は2つのスレッドを持っています。キューから読み取るもの。while(1) で読み取りを実行したくないので、ループごとに条件変数を与えることを考えています。

while(1){
    while queue is not empty
        wait(cond)
        pop() 
}

それ以外の:

while(1){
  while queue is not empty
      pop
}

キューにプッシュするスレッド. 待機してシグナル メソッドを使用する場合、そのスレッドは、プッシュするたびに (!) ポップ スレッドにシグナルを送信して通知する必要があります。キューがほとんど空でない場合は、シグナルを送信しても意味がありません (または空ではないでしょうか?) ポップ スレッドが待機していないため、パフォーマンスが低下するのではないかと心配しています。ただし、キューが半分の時間空である場合、2 番目のポップ方法のようにキューをループすると、ビジーな待機になる可能性があります。

ここの誰かが、待機していないスレッドにシグナルを送信しても問題ないという事実を失格にすることで、私の恐怖を解消してくれることを願っています

ありがとう

4

1 に答える 1

0

まず、念のため、ある意味でpthread_cond_signalを送信しないでください。条件変数にフラグを立て、それを待機している変数を解放するだけです。したがって、消費プロセスがうまく呼び出す前に呼び出すと、それは無視されます。signalsignal(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;
}
于 2012-12-04T18:19:52.560 に答える