C++ 条件变量( 三个线程轮流打印字符 )

最近 时候, 问了我一个问题,就是创建三个线程轮流打印字符,问我有什么方法,学艺不精,想了一会只想到一个通过判断全局变量数字通过阻塞的方式完成轮流打印字符功能,然后上网查资料,看到两篇不错的文章,引用一下:http://blog.csdn.net/baiding1123/article/details/14053957 和 http://blog.chinaunix.net/uid-20628302-id-1608577.html

这个方法的实现主要就是通过 pthread_cond_wait(pthread_cond_t * ,pthread_mutex_t *) 和pthread_cond_broadcast(pthread_cond_t * )两个方法来实现。

pthread_cond_wait方法实现的功能就是,先对互斥量解锁,然后判断条件是否成立,成立则给互斥量上锁,然后返回,不成立则等待,不占有cpu资源。

引用人家的伪代码:

lock(mutex)   ----------------a.lock
pthread_cond_wait()
{
    unlock(mutex)-------------a.unlock
    if ( 条件不满足)
      睡觉
    else 
    {
      lock(mutex)-------------b.lock
      return
    }
}

dosomething();

unlock(mutex);---------------b.unlock

pthread_cond_broadcast方法我理解的就是:这个函数会将pthread_cond_t 条件置为可用,然后向这个进程所有的线程发送广播唤醒休眠的线程。

然后看了人家的程序和解释,自己动手写代码测试了一下。开始一直在一个地方出错,后来解决了。(问题出在,调用pthread_cond_broadcast 方法时候必须确保目的线程已经调用了pthread_cond_wait 方法,否则,pthread_cond_wait 将接收不到广播,从而不会从休眠状态退出,运行程序。简单来说就是 pthread_cond_wait 必须先于 pthread_cond_broadcast方法运行)

代码:

 

#include<pthread.h>
#include<iostream>
using namespace std;


pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

//condition valiable
pthread_cond_t cond_a=PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_b=PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_c=PTHREAD_COND_INITIALIZER;

//declared the thread has been wait
bool flag_a=false;
bool flag_b=false;
bool flag_c=false;


void pth_wait(bool *flag,pthread_cond_t * cond,pthread_mutex_t *mutex)
{
    *flag=true;
    pthread_cond_wait(cond,mutex);
    *flag=false;
}

void pth_broadcast(bool *flag,pthread_cond_t *cond,pthread_mutex_t *mutex)
{
    while(!(*flag)){
        pthread_mutex_unlock(mutex);
        usleep(50);
        pthread_mutex_lock(mutex);
    }
    
    pthread_cond_broadcast(cond);

}

void *pth_a(void *arg)
{
    int i=*(int *)arg;
    while(i--){
        pthread_mutex_lock(&mutex);
        cout << "A wait..." << endl;
        pth_wait(&flag_a,&cond_a,&mutex);
        cout << "A " << i << endl;
        pth_broadcast(&flag_b,&cond_b,&mutex);
        pthread_mutex_unlock(&mutex);
    }
    
    flag_a=true;
}

void *pth_b(void *arg)
{
    int i=*(int *)arg;
    while(i--){
        pthread_mutex_lock(&mutex);
        cout << "B wait..." << endl;
        pth_wait(&flag_b,&cond_b,&mutex);
        cout << "B " << i << endl;
        pth_broadcast(&flag_c,&cond_c,&mutex);
        pthread_mutex_unlock(&mutex);
    }

}

void *pth_c(void *arg)
{
    int i=*(int *)arg;
    while(i--){
        pthread_mutex_lock(&mutex);
        cout << "C wait..." << endl;
        pth_wait(&flag_c,&cond_c,&mutex);
        cout << "C " << i << endl;
        pth_broadcast(&flag_a,&cond_a,&mutex);
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    pthread_t pid_a,pid_b,pid_c;
    int count=10;
    if(pthread_create(&pid_a,NULL,pth_a,&count)<0)
        return 0;
    if(pthread_create(&pid_b,NULL,pth_b,&count)<0)
        return 0;
    if(pthread_create(&pid_c,NULL,pth_c,&count)<0)
        return 0;
    
    usleep(4000);
    pthread_mutex_lock(&mutex);
    pthread_cond_broadcast(&cond_a);
    pthread_mutex_unlock(&mutex);
    
    pthread_join(pid_a,NULL);
    pthread_join(pid_b,NULL);
    pthread_join(pid_c,NULL);
    

     pthread_mutex_destroy(&mutex);
     pthread_cond_destroy(&cond_a);
     pthread_cond_destroy(&cond_b);
     pthread_cond_destroy(&cond_c);


return 0; }

 

在第一次唤醒a线程时,必须确保A线程已经调用过pthread_cond_wait 函数,处在休眠状态

 

posted on 2017-04-11 14:52  Just_Boy  阅读(1215)  评论(0)    收藏  举报