条件变量

http://blog.csdn.net/lanyan822/article/details/7586845

条件变量用pthread_cond_t数据类型表示。
条件变量本身由互斥量保护,所以在改变条件状态前必须锁住互斥量。

条件变量初始化:

第一种,赋值常量PTHREAD_COND_INITIALIZER;第二种,使用pthread_cond_init函数
int pthread_cond_init (pthread_cond_t *__restrict __cond,  
                  __const pthread_condattr_t *__restrict  
                  __cond_attr);  
int pthread_cond_destroy (pthread_cond_t *__cond); 

条件等待

使用pthread_cond_wait等待条件为真。
    pthread_cond_wait (pthread_cond_t *__restrict __cond,  
                  pthread_mutex_t *__restrict __mutex)  

这里需要注意的是,调用pthread_cond_wait传递的 互斥量已锁定,pthread_cond_wait将调用线程放入等待条件的线程列表,然后释放互斥量,在pthread_cond_wait返回时,再次锁定互斥量。

唤醒线程

pthread_cond_signal唤醒等待该条件的某个线程,pthread_cond_broadcast唤醒等待该条件的所有线程。
    int pthread_cond_signal (pthread_cond_t *__cond);  
      
    int pthread_cond_broadcast (pthread_cond_t *__cond)  

主线程启动4个线程,每个线程有一个参数i(i=生成顺序),无论线程的启动顺序如何,执行顺序只能为,线程0、线程1、线程2、线程3。
    #include <stdio.h>  
    #include <stdlib.h>  
    #include <pthread.h>  
    #include <unistd.h>  
    #include <string.h>  
    #define DEBUG 1  
      
    int num=0;  
    pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;  
    pthread_cond_t qready=PTHREAD_COND_INITIALIZER;  
    void * thread_func(void *arg)  
    {  
        int i=(int)arg;   
        int ret;  
        sleep(5-i);//线程睡眠,然最先生成的线程,最后苏醒  
        pthread_mutex_lock(&mylock);//调用pthread_cond_wait前,必须获得互斥锁  
        while(i!=num)  
        {  
    #ifdef DEBUG  
            printf("thread %d waiting\n",i);  
    #endif  
            ret=pthread_cond_wait(&qready,&mylock);//该函数把线程放入等待条件的线程列表,然后对互斥锁进行解锁,这两部都是原子操作。并且在pthread_cond_wait返回时,互斥量再次锁住。  
            if(ret==0)  
            {  
    #ifdef DEBUG  
                printf("thread %d wait success\n",i);  
    #endif  
            }else  
            {  
    #ifdef DEBUG  
                printf("thread %d wait failed:%s\n",i,strerror(ret));  
    #endif  
            }  
        }  
        printf("thread %d is running \n",i);  
        num++;  
        pthread_mutex_unlock(&mylock);//解锁  
        pthread_cond_broadcast(&qready);//唤醒等待该条件的所有线程  
        return (void *)0;  
    }  
    int main(int argc, char** argv) {  
          
        int i=0,err;  
        pthread_t tid[4];  
        void *tret;  
        for(;i<4;i++)  
        {  
            err=pthread_create(&tid[i],NULL,thread_func,(void *)i);  
            if(err!=0)  
            {  
                printf("thread_create error:%s\n",strerror(err));  
                exit(-1);  
            }  
        }  
        for (i = 0; i < 4; i++)  
        {  
            err = pthread_join(tid[i], &tret);  
            if (err != 0)  
            {  
                printf("can not join with thread %d:%s\n", i,strerror(err));  
                exit(-1);  
            }  
        }  
        return 0;  
    }  

在DEBUG模式可以看出,线程3先被唤醒,然后执行pthread_cond_wait(输出thread 3 waiting),此时在pthread_cond_wait中先解锁互斥量,然后进入等待状态。这是thread 2加锁互斥量成功,进入pthread_cond_wait(输出thread 2 waiting) ,同样解锁互斥量,然后进入等待状态。直到线程0,全局变量与线程参数i一致,满足条件,不进入条件等待,输出thread 0 is running。全局变量num执行加1操作,解锁互斥量,然后唤醒所有等待该条件的线程。thread 3 被唤醒,输出thread 3 wait success。但是不满足条件,再次执行pthread_cond_wait。如此执行下去,满足条件的线程执行,不满足条件的线程等待。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值