pthread_cond_wait 不解锁互斥体

发布于 2024-08-02 11:11:07 字数 1479 浏览 9 评论 0原文

我在网上找不到任何证据表明 pthread_cond_wait 在 Mac OS X 上很奇怪,但对我来说,它似乎没有通过最简单的测试。

该函数

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_wait 之后添加 pthread_mutex_unlock,它的行为将按预期进行。 (或者只用一半的锁定机制就可以达到您的预期。)那么,有什么作用呢?

I can't find any evidence online of pthread_cond_wait being strange on Mac OS X, but it seems to be failing the simplest test for me.

The function

int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t * );

is supposed to unlock the mutex argument #2 and then wait for a signal to be sent on the condition argument #1. I wrote a simple program to test this, and also test for spurious wakeups:

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

But it only acquires the lock once. The main thread doesn't even try to acquire the lock just to keep things simple.

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

signaled
expected 1

signaled

signaled

If I add a pthread_mutex_unlock after the pthread_cond_wait, it behaves as expected. (Or as well as you'd expect with only half a locking mechanism.) So, what gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遮了一弯 2024-08-09 11:11:07

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. 

pthread_cond_wait re-acquires the mutex when it is awoken. The standard pattern for using pthreads mutexes is:

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

This behavior is described in the SUS documentation for pthread_cond_wait as:

Upon successful return, the mutex has been locked and is owned by the calling thread. 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文