zoukankan      html  css  js  c++  java
  • [多线程学习笔记]条件变量

    关于条件变量这一节的知识几乎惹怒了我,不知道是原书就不好,还是翻译的不好,还是我笨的原因,总而言之就是看不懂。

    现在说一下我的理解:

    条件变量虽说是和某个谓词绑定,但是其实只是程序员的工作,并没有真正的绑定。

    使用条件变量的场景是,一个队列空了,我们要等待它不为空,虽然也不知道谁规定的,大家都用while,而不用if

    while(QUEUE_IS_EMPTY())

    {

      pthread_cond_wait(&cond,&mutex);

    }

    /*************************************************************************
        > File Name: lifecycle.c
        > Author: likeyi
        > Mail: likeyiyy@sina.com 
        > Created Time: Thu 17 Apr 2014 11:00:08 AM CST
     ************************************************************************/
                        
    #include <stdio.h> 
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond   = PTHREAD_COND_INITIALIZER;
    int a,b;            
    void * delay_print(void * arg)
    {                   
        pthread_detach(pthread_self());
        sleep(1);       
        printf("Hello world
    ");
        a = 7;          
        b = 8;          
        pthread_cond_signal(&cond);
                        
    }                   
    int main(int argc,char * argv[])
    {                   
        pthread_t tid; 
        int result = pthread_create(&tid,NULL,delay_print,NULL);
        if(result != 0)
        {               
            printf("create thread error
    ");
            exit(0);    
        }               
        printf("printf form main
    ");
        a = 6;          
        b = 5;          
        if(a != b)      
        {               
            pthread_cond_wait(&cond,&mutex);
        }               
        printf("a= %d b = %d
    ",a,b);
        pthread_exit(&result);
    }  

    如上面的代码所示,当a不等于b时我们就等待,从这个逻辑上来说我们是期望当a等于b的时候把我们唤醒。

    然而事实上,这个绑定只是程序员的主观愿望,上面的代码,在子线程中我们让a=8,b=9,然后调用了pthread_cond_signal,仍然唤醒了主线程。

    这是多么不好的语义啊,完全靠程序员自己来进行绑定啊。

    有没有一种操作是原子的等待wait bool is 1

    比如说atomic_wait(a==b),我希望有这样的函数。

    /***********************************************************************************************************/

    从上面的代码我们也能看出,之所以要用while而不用if的原因,书上讲了三个原因:

    被拦截的唤醒,松散的唤醒,假唤醒。不知道假唤醒是不是我这样的假的唤醒。

    总而言之:总是在while循环中测试谓词来等待条件变量。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond   = PTHREAD_COND_INITIALIZER;
    int a,b;
    void * delay_print(void * arg)
    {
        pthread_detach(pthread_self());
        sleep(1);
        printf("Hello world
    ");
        a = 8;
        b = 8;
        pthread_cond_signal(&cond);
    
    }
    int main(int argc,char * argv[])
    {
        pthread_t tid;
        int result = pthread_create(&tid,NULL,delay_print,NULL);
        if(result != 0)
        {
            printf("create thread error
    ");
            exit(0);
        }
        printf("printf form main
    ");
        a = 6;
        b = 5;
        while(a != b)
        {
            pthread_cond_wait(&cond,&mutex);
        }
        printf("a= %d b = %d
    ",a,b);
        pthread_exit(&result);
    }
    防止假唤醒

     一个条件变量只能对应一个互斥量。

    一个互斥量可以对应多个条件变量。

    mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),

    且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),

    而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。

    在条件满足从而离开pthread_cond_wait()之前,

    mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。

  • 相关阅读:
    npm install node-echarts npm ERR! code ELIFECYCLE
    MySql-Proxy之多路结果集归并
    Error: Cannot find module 'is-accessor-descriptor'
    如何在Node.js实现兼容ES6
    perl 自动识别编码,转换编码
    Mixin result declared without body
    Python爬虫入门教程 48-100 使用mitmdump抓取手机惠农APP-手机APP爬虫部分
    unexpected token "indent"
    Radware:上周五美国大规模DDoS攻击是如何发生的
    Radware:上周五美国大规模DDoS攻击是如何发生的
  • 原文地址:https://www.cnblogs.com/likeyiyy/p/3670286.html
Copyright © 2011-2022 走看看