4

Mac OS X で奇妙な動作をするという証拠をオンラインで見つけることはできませんがpthread_cond_wait、私にとって最も単純なテストでは失敗しているようです。

関数

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;
}

ただし、ロックを取得するのは 1 回だけです。メインスレッドは、物事を単純にするためだけにロックを取得しようとさえしません。

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

signaled
expected 1

signaled

signaled

pthread_mutex_unlockの後にa を追加するとpthread_cond_wait、期待どおりに動作します。(または、ロック機構の半分だけで期待どおりです。) それで、何が得られますか?

4

1 に答える 1

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 のドキュメントでpthread_cond_wait次のように説明されています。

Upon successful return, the mutex has been locked and is owned by the calling thread. 
于 2009-08-23T23:28:02.647 に答える