当前位置: 首页 > 面试题库 >

何时使用pthread条件变量?

罗甫
2023-03-14
问题内容

pthread问题:

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

我的问题是: 什么时候应该使用条件变量?

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

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

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

这是一个测试:

文件condvar.c

#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

问题答案:

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

// 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);

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

// 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)


 类似资料:
  • 我在C中做了一个关于线程、锁和条件变量的练习。我需要编写一个程序来获取数据,将其转换为一个链表,启动3个线程,每个线程为列表中的每个节点计算结果,主线程在evreyone完成后打印结果。 这是主要功能: 请注意,create_numbers功能正常工作,列表按预期工作。 以下是启动线程和线程功能代码: 请注意,self_id用于调试目的。 我的主要问题是分工合作。每个线程从全局链表中获取一个元素,

  • 我试图在C语言中实现用餐哲学家的问题,使用pthon、互斥锁和条件变量。 它需要一个命令行参数来指定程序应该运行多长时间。我必须使用睡眠功能来完成这项任务 我的输出有一些问题: 使主函数在命令行上输入的秒数处于Hibernate状态似乎并没有使输出不同。 大多数哲学家都在渴望程序的大部分执行。 当我打印出一个哲学家在思考或吃饭时,一个“哲学家5”出现了,尽管应该只有0-4个哲学家。 这是我的密码:

  • 问题内容: 假设您具有以下pyspark DataFrame: 接下来的两个代码块应该做同样的事情-即,如果不是,则返回该列的大写。但是,第二种方法(使用)会产生错误。 方法1 :使用 方法2 :在内部使用 这给了我。为什么调用中的检查似乎被忽略了? 我知道我可以改变我要避免这种错误,但我想知道为什么它的发生。 完整回溯 : 问题答案: 您必须记住,Spark SQL(与RDD不同)不是您所看到的

  • 问题内容: 最近,我开始将ucos-ii移植到Ubuntu PC。 众所周知,在ucos-ii中无法通过在pthread的回调函数中的“ while”循环中添加一个标记来执行暂停和恢复来模拟“进程”,以执行暂停和恢复操作(类似于下面的解决方案)。因为ucos- ii中的“进程”可以随时暂停或恢复! 我在下面的网站上找到了一种解决方案,但是由于过时而无法构建。它使用Linux中的进程来模拟ucos-

  • 本文向大家介绍浅谈Linux条件变量的使用,包括了浅谈Linux条件变量的使用的使用技巧和注意事项,需要的朋友参考一下 Linux线程同步之间存在多种机制,条件变量是一种类似操作系统里提到的生产者-消费者算法的同步机制,允许线程以无竞争的方式等待特定条件的发生。 示例伪代码: 条件变量需要配合互斥量一起使用,互斥量作为参数传入wait函数,函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,

  • 条件变量 条件变量(conditional variable)的常见接口是这样的: wait:当前线程开始等待这个条件变量 notify_one:让某一个等待此条件变量的线程继续运行 notify_all:让所有等待此变量的线程继续运行 条件变量和互斥锁的区别在于,互斥锁解铃还须系铃人,但条件变量可以由任何来源发出 notify 信号。同时,互斥锁的一次 lock 一定对应一次 unlock,但条