何时使用pthread条件变量? [英] When to use pthread condition variables?

查看:82
本文介绍了何时使用pthread条件变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

pthread问题:

pthread question:

看来,只有在其他线程调用pthread_cond_notify之前调用pthread_cond_wait时,条件变量才起作用. 如果在等待之前以某种方式发生通知,则等待将卡住.

it appears that a condition variable only works if pthread_cond_wait is called before the other thread calls pthread_cond_notify. If notify somehow happens before wait then wait will be stuck.

我的问题是: 何时应使用条件变量?

My question is: when should condition variables be used?

调度程序可以抢占线程,并且在等待之前可能会发生通知.

The scheduler can preempt threads and a notify may happen before wait.

等待信号量没有这个问题-它们有一个计数器.

Waiting on semaphores does not have this problem -- these have a counter.

什么时候条件变量比信号量更好?

When is a conditional variable better than a semaphore?

这是一个测试:

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

// test of conditional variables;
// if cond-var is notified before wait starts, then wait never wakes up !!!
// better to use semaphores than this crap.

pthread_mutex_t cond_var_lock =  PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;

int wait_first = 1;

void *tfunc(void *arg)
{
    (void) arg;

    if (!wait_first)
        sleep(1);

    fprintf(stderr,"on enter cond_var_lock %lx\n", pthread_self());
    pthread_mutex_lock( &cond_var_lock);
    fprintf(stderr,"before pthread_cond_wait %lx\n", pthread_self());
    pthread_cond_wait( &cond_var, &cond_var_lock);
    fprintf(stderr,"after pthread_cond_wait %lx\n", pthread_self());
    pthread_mutex_unlock( &cond_var_lock);
    fprintf(stderr,"after exit cond_var_lock %lx\n", pthread_self());

    return 0;
}

int main(int argc, char *argv[])
{
    pthread_t th;

    if (argc > 0) 
    wait_first = atoi( argv[1] );

    if (wait_first)
    {
        fprintf(stderr,"********* Wait first ***********\n");
    } else {
        fprintf(stderr,"********* Notify first *********\n");
    }


    pthread_create( &th, 0, tfunc, 0 );

    if (wait_first)
    {
        sleep(1);
    } 

    fprintf(stderr, "! on enter cond_var_lock %lx\n", pthread_self());
    pthread_mutex_lock( &cond_var_lock);
    fprintf(stderr, "! before pthread_cond_signal %lx\n", pthread_self());
    pthread_cond_signal( &cond_var );
    fprintf(stderr, "! after pthread_cond_signal %lx\n", pthread_self());
    pthread_mutex_unlock( &cond_var_lock);
    fprintf(stderr, "! after exit cond_var_lock %lx\n", pthread_self());

    sleep(5);
    return 0;    
}

文件test.sh

#!/bin/sh

set -e
set -x

gcc condvar.c -o condvar -lpthread

./condvar 1

./condvar 0

测试输出

Output:

+ gcc condvar.c -o condvar -lpthread
+ ./condvar 1
********* Wait first ***********
on enter cond_var_lock b7779b70
before pthread_cond_wait b7779b70
! on enter cond_var_lock b777a6c0
! before pthread_cond_signal b777a6c0
! after pthread_cond_signal b777a6c0
! after exit cond_var_lock b777a6c0
after pthread_cond_wait b7779b70
after exit cond_var_lock b7779b70
+ ./condvar 0
********* Notify first *********
! on enter cond_var_lock b785c6c0
! before pthread_cond_signal b785c6c0
! after pthread_cond_signal b785c6c0
! after exit cond_var_lock b785c6c0
on enter cond_var_lock b785bb70
before pthread_cond_wait b785bb70

推荐答案

条件变量应用作等待和通知的地方.它们不是条件本身,也不是事件.条件包含在周围的编程逻辑中.条件变量的典型用法是

Condition variables should be used as a place to wait and be notified. They are not the condition itself and they are not events. The condition is contained in the surrounding programming logic. The typical usage pattern of condition variables is

// safely examine the condition, prevent other threads from
// altering it
pthread_mutex_lock (&lock);
while ( SOME-CONDITION is false)
    pthread_cond_wait (&cond, &lock);

// Do whatever you need to do when condition becomes true
do_stuff();
pthread_mutex_unlock (&lock);

另一方面,一个线程发出条件变量的信号, 通常看起来像

On the other hand, a thread, signaling the condition variable, typically looks like

// ensure we have exclusive access to whathever comprises the condition
pthread_mutex_lock (&lock);

ALTER-CONDITION

// Wakeup at least one of the threads that are waiting on the condition (if any)
pthread_cond_signal (&cond);

// allow others to proceed
pthread_mutex_unlock (&lock)

这篇关于何时使用pthread条件变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆