• linux中的条件变量


    1 条件变量认识

    (1)大家可能知道互斥量是线程程序中必须的工具了,但是也不能是万能的,就比如某个线程正在等待共享数据某个条件的发生,这个时候会发生什么呢。它就可能重复的尝试对互斥对象锁定和解锁来检查共享数据结构。

    (2)线程在等待满足某些条件的时候使线程进入睡眠状态,一旦条件满足了就唤醒并等待满足特定条件而睡眠的线程。

    (3)条件变量一般都允许线程阻塞和等待另一个线程发送信号的方法来弥补互斥锁的不足。

    2 函数介绍

    (1) 静态方式使用 pthread_cond_t cond=PTHREAD_COND_INITIALIZER

    动态方式 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr)

    -------->当cond_attr为null的时候使用默认的属性。

    (2)注销一个条件变量

    int pthread_cond_destroy(pthread_cond_t *cond)只有没有线程在这个条件变量的时候才能注销这个条件变量。

    (3)等待有两种方式,条件等待和时间等待。无论哪种等待都必须和一个互斥锁配合来防止多个线程同时请求pthread_cond_wait()这个竞争条件。

    (4)激发 两种方式,pthread_cond_signal()激活一个等待该条件的线程。pthread_cond_broadcast()激活所有等待线程。

    3 例子

    (1)第一个例子

     1 #include <iostream>
     2 #include <pthread.h>
     3 #include <unistd.h>
     4 using namespace std;
     5 pthread_cond_t qready = PTHREAD_COND_INITIALIZER;    /*初始构造条件变量*/
     6 pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;    /*初始构造锁*/
     7 int x = 10;
     8 int y = 20;
     9 void *func1(void *arg){
    10     cout<<"func1 开始"<<endl;
    11     pthread_mutex_lock(&qlock);
    12     while(x<y)
    13     {
    14         pthread_cond_wait(&qready,&qlock);
    15     }
    16     pthread_mutex_unlock(&qlock);
    17     sleep(3);
    18     cout<<"func1 结束"<<endl;
    19 }
    20 void *func2(void *arg){
    21     cout<<"func2 开始"<<endl;
    22     pthread_mutex_lock(&qlock);
    23     //修改xy
    24     x = 20;
    25     y = 10;
    26     cout<<"has change x and y"<<endl;
    27     pthread_mutex_unlock(&qlock);
    28     if(x > y){
    29         pthread_cond_signal(&qready);//发送信号 使线程1不阻塞
    30     }
    31     cout<<"func2 结束"<<endl;
    32 }
    33 int main(int argc,char **argv){
    34     pthread_t tid1,tid2;
    35     int iRet;
    36     iRet = pthread_create(&tid1,NULL,func1,NULL);
    37     if(iRet){
    38         cout<<"pthread 1 create error"<<endl;
    39         return iRet;
    40     }
    41     sleep(2);
    42     iRet = pthread_create(&tid2,NULL,func2,NULL);
    43     if(iRet){
    44         cout<<"pthread 2 create error"<<endl;
    45         return iRet;
    46     }
    47     sleep(5);    
    48     return 0;    
    49 }
    View Code

    (2)第二个例子

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <unistd.h>
     5 #include <pthread.h>
     6 #include <errno.h>
     7 #include <iostream>
     8 #include <pthread.h>
     9 using namespace std;
    10 
    11 /*提示出租车到达的条件变量*/
    12 pthread_cond_t taxiCond = PTHREAD_COND_INITIALIZER; 
    13 /*同步锁*/
    14 pthread_mutex_t taxiMutex = PTHREAD_MUTEX_INITIALIZER;   
    15 
    16 int travelerCound=0;
    17 //旅客到来的时候 数量加上1
    18 void * traveler_arrive(void * name){
    19     cout<<"Traveler: "<<(char *)name<<" needs a taxi now!"<<endl;
    20     pthread_mutex_lock(&taxiMutex);
    21     travelerCound++;
    22     pthread_cond_wait(&taxiCond,&taxiMutex);
    23     pthread_mutex_unlock(&taxiMutex);
    24     cout<<"Traveler: "<<(char *)name<<" now got a taxi!"<<endl;
    25     pthread_exit((void*)0);
    26 }
    27 
    28 void * taxi_arrive(void * name){
    29     cout<<"Taxi: "<<(char *)name<<" arrives."<<endl;
    30     //保证先来的检测是否有新的顾客到达
    31     while(1){
    32         pthread_mutex_lock(&taxiMutex);
    33         //大于则通知
    34         if(travelerCound>0){
    35             pthread_cond_signal(&taxiCond);
    36             pthread_mutex_unlock(&taxiMutex);    
    37             break;            
    38         }
    39         pthread_mutex_unlock(&taxiMutex);
    40     }
    41     pthread_exit((void*)0);
    42 }
    43 
    44 int main(){
    45     pthread_t tids[3];
    46     int iRet = pthread_create(&tids[0],NULL,taxi_arrive,(void*)(" Jack "));
    47     if(iRet){
    48         printf("pthread_create error: iRet=%d
    ",iRet);
    49         return iRet;
    50     }
    51     printf("Time passing by.
    ");
    52     sleep(1);
    53     iRet = pthread_create(&tids[1],NULL,traveler_arrive,(void*)(" Susan "));
    54     if(iRet){
    55         printf("pthread_create error: iRet=%d
    ",iRet);
    56         return iRet;
    57     }
    58     printf("Time passing by.
    ");
    59     sleep(1);    
    60     iRet = pthread_create(&tids[2],NULL,taxi_arrive,(void*)(" Mike "));
    61     if(iRet){
    62         printf("pthread_create error: iRet=%d
    ",iRet);
    63         return iRet;
    64     }    
    65     printf("Time passing by.
    ");
    66     sleep(1);
    67     
    68     void *retval;    
    69     for(int i=0;i<3;i++){
    70         iRet=pthread_join(tids[i],&retval);
    71         if (iRet){
    72             printf("pthread_join error: iRet=%d
    ",iRet);
    73             return iRet;
    74         }
    75         printf("retval=%ld
    ",(long)retval);    
    76     }
    77     return 0;    
    78 }

    好叻 加油!!!!

  • 相关阅读:
    Domain Model
    linux 后台运行命令
    morphia(3)-查询
    [八省联考2018] 劈配
    [BZOJ 3218] a+b Problem
    [学习笔记] KM算法
    [HNOI2013] 消毒
    [HNOI2014] 画框
    [HDU 6057] Kanade's convolution
    [模板] 任意模数多项式乘法
  • 原文地址:https://www.cnblogs.com/lanjianhappy/p/8985683.html
Copyright © 2020-2023  润新知