2009-08-23 4 views
4

オンラインでMac OS Xでpthread_cond_waitという奇妙な証拠は見つかりませんでしたが、私にとっては最も簡単なテストでは失敗しているようです。pthread_cond_waitはmutexのロックを解除しません

機能

int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); 

はミューテックス引数#2のロックを解除した後、条件引数#1上で送信される信号を待つことになっています。私はこれをテストするための簡単なプログラムを書いた、ともスプリアスウェイクアップのためのテスト:

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

pthread_t spin_thread; 
pthread_mutex_t spin_mutex; 
pthread_cond_t spin_cond; 

int actual = 0; 

void *condspin(void *v) { 
    int expected = 0; 
    for (;;) { 
     if (actual != expected) printf("unexpected %d\n", actual); 
     else printf("expected %d\n", actual); 
     pthread_mutex_lock(&spin_mutex); 
     printf("locked\n"); 
     expected = actual + 1; 
     pthread_cond_wait(&spin_cond, &spin_mutex); 
    } 
    return NULL; 
} 

int main(int argc, char ** argv) { 
    pthread_mutex_init(&spin_mutex, NULL); 
    pthread_cond_init(&spin_cond, NULL); 
    pthread_create(&spin_thread, NULL, &condspin, NULL); 

    for (;;) { 
     getchar(); 
     pthread_cond_signal(&spin_cond); 
     printf("signaled\n"); 
     ++ actual; 
    } 
    return 0; 
} 

しかし、それは一度だけロックを取得します。メインスレッドは物事を単純に保つためだけにロックを取得しようとしません。

Shadow:~ dkrauss$ cc condwait.c -o condwait 
Shadow:~ dkrauss$ ./condwait 
expected 0 
locked 

signaled 
expected 1 

signaled 

signaled 

私はpthread_cond_waitpthread_mutex_unlockを追加する場合は、予想通り、それが動作します。 (あるいは、ロック機構の半分しか期待していなかったとしても)だから、何が得られますか?

答えて

8

pthread_cond_waitは、覚醒時にミューテックスを再取得します。 pthreadsのミューテックスを使用するための標準的なパターンは次のとおりです。

pthread_mutex_lock(&mutex); 
// init work... 
while (!some_condition) 
    pthread_cond_wait(&cond, &mutex); 
// finishing work... 
pthread_mutex_unlock(&mutex); 

この動作は次のようにSUS documentation for pthread_cond_waitで説明します。

Upon successful return, the mutex has been locked and is owned by the calling thread. 
+0

なるほど!理にかなっている!今私が読んだドキュメント(と私はいくつかを読んで)のいずれかがなぜそう言っていないのですか? – Potatoswatter

+0

これはSUS仕様(引用が追加されました)とpthread_cond_waitのlinuxthreadsのマンページに記載されています。 Mac OS Xについてはわかりませんが、これも文書化してください... – bdonlan

+2

OS Xにはほとんどドキュメントがありません。 pthread_cond_wait()関数は、mutex引数を原子的にロック解除し、cond引数で待機します。私はあなたが提供した参考資料を実際に読んだことがありますが、私は受動的な声の使用によって混乱しました。 「ミューテックスがロックされました」とは、特に、多くの要件がユーザーに当てはまるインターフェイスで、「関数がミューテックスをロックする」という混乱する方法です。 – Potatoswatter