70

一般的に言えば、以下のようpthread_cond_wait()pthread_cond_signal()呼ばれます。

//thread 1:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
do_something()
pthread_mutex_unlock(&mutex);

//thread 2:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);  
pthread_mutex_unlock(&mutex);

手順は次のとおりです。

  1. pthread_cond_wait(&cond, &mutex);が呼び出され、ミューテックスのロックを解除します

  2. スレッド 2 はミューテックスをロックし、ミューテックスのpthread_cond_signal()ロックを解除する を呼び出します。

  3. スレッド 1 でpthread_cond_wait()呼び出され、ミューテックスを再度ロックします。

スレッド 2 では、pthread_cond_signal()呼び出された後、 pthread_mutex_unlock(&mutex)実行しようとしていますが、現在スレッド 1 によってロックされているミューテックスのロックを解除したいようです。私の理解に問題はありますか?

pthread_cond_wait()また、同じ cond-mutex ペアに対して 1 つのスレッドからしか呼び出せないようにも思えます。しかし、「pthread_cond_signal() 関数は、指定された条件変数 cond でブロックされているスレッドの少なくとも 1 つのブロックを解除する必要があります (cond でブロックされているスレッドがある場合)」という格言があります。つまり、pthread_cond_wait()同じ cond-mutex ペアに対して多くのスレッドから呼び出すことができるということですか?

4

3 に答える 3

124

pthread_cond_signalミューテックスをロック解除しません (ミューテックスへの参照がないため、ロックを解除するものをどのように知ることができますか?) 実際、信号はミューテックスに接続する必要はありません。シグナル スレッドはミューテックスを保持する必要はありませんが、条件変数に基づくほとんどのアルゴリズムでは必要になります。

pthread_cond_wait(お気づきのように)スリープする直前にミューテックスのロックを解除しますが、ウェイクアップする前に、シグナルが送信されると(待機が必要になる場合があります)ミューテックスを再取得します。そのため、シグナル スレッドがミューテックスを保持している場合 (通常のケース)、待機中のスレッドは、シグナル スレッドがミューテックスのロックを解除するまで処理を続行しません。

条件変数の一般的な使用法は次のようなものです。

thread 1:
    pthread_mutex_lock(&mutex);
    while (!condition)
        pthread_cond_wait(&cond, &mutex);
    /* do something that requires holding the mutex and condition is true */
    pthread_mutex_unlock(&mutex);

thread2:
    pthread_mutex_lock(&mutex);
    /* do something that might make condition true */
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

2 つのスレッドには、ミューテックスがアクセスを保護している共有データ構造があります。最初のスレッドは、何らかの条件が true になるまで待機してから、すぐに何らかの操作を実行します (条件チェックとアクションの間に他のスレッドが競合状態になり、条件を false にする機会はありません)。条件を真にして、それを待っている可能性のある人を起こす必要があります。

于 2013-05-13T14:10:10.000 に答える
1

ここから例を挙げました https://www.geeksforgeeks.org/condition-wait-signal-multi-threading/

これに変更し、

#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 

// Declaration of thread condition variable 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 

// declaring mutex 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

// Thread function 
void releaseFun() 
{ 
    // Let's signal condition variable cond
    printf("Signaling condition variable cond\n"); 
    pthread_cond_signal(&cond); 
}

// Thread function 
void* blockedThread() 
{
    // acquire a lock 
    pthread_mutex_lock(&lock); 
    printf("Waiting on condition variable cond\n");
    pthread_cond_wait(&cond, &lock); 
    // release lock 
    pthread_mutex_unlock(&lock); 

    printf("Returning thread\n"); 

    return NULL; 
}    

// Driver code 
int main() 
{ 
    pthread_t tid;

    // Create thread 1 
    pthread_create(&tid, NULL, blockedThread, NULL); 

    // sleep for 1 sec so that thread 1 
    // would get a chance to run first 
    sleep(1); 

    releaseFun();
    // wait for the completion of thread 2 
    pthread_join(tid, NULL); 

    return 0; 
}

出力: gcc test_thread.c -lpthread

条件変数 cond 待ち

シグナリング条件変数 cond

戻るスレッド

スレッドのロックとロック解除は、blockThread の pthread_cond_wait() 関数がブロック解除されるように通知された場合にのみ発生します。

于 2020-09-16T08:43:14.490 に答える