pthread_cond_wait的理解

使用流程

等待线程:

pthread_mutex_lock(&mutex);

if(条件不满足)

  pthread_cond_wait(&cond, &mutex);

//处理共享资源

pthread_mutex_unlock(&mutex);

激活线程:

pthread_mutex_lock(&mutex);

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

下面写了一个例子

复制代码

复制代码

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
using namespace std;

int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 
//该函数增加count数值
void * creator(void * arg)
{
    cout << "creator add lock" << endl;
    pthread_mutex_lock(&mutex);

    count ++;

    cout << "in creator count is : " << count << endl;
    //条件满足时发送信号
    if(count > 0)
    {

        pthread_cond_signal(&cond);
    }

    
    cout << "creator release lock" << endl;
    
    pthread_mutex_unlock(&mutex);

    return NULL;

}

//该函数减少count数值
void * consumer(void * arg)
{
    cout << "consumer add lock" << endl;

    pthread_mutex_lock(&mutex);
    //当条件不满足时等待
    if(count <= 0)
    {
        cout << "begin wait" << endl;
        pthread_cond_wait(&cond,&mutex);
        cout << "end wait" << endl;
    }

    count --;

    cout << "in consumer count is " << count << endl;

    pthread_mutex_unlock(&mutex);

    cout << "consumer release lock" << endl;
    
    return NULL;
    
}


int main()
{
    //两个线程,一个生产者线程一个消费者线程
    pthread_t createthread,consumethread;

     pthread_create(&consumethread, NULL, consumer, NULL);
   sleep(2);
    pthread_create(&createthread, NULL, creator, NULL);
    
    //主进程等待两个线程结束
    pthread_join(createthread, NULL);
    pthread_join(consumethread, NULL);
    return 0;
}

复制代码

复制代码

因为消费者线程先跑起来,会等待生产者增加count数量,所以打印输出结果如下

下面将消费者和生产者线程增加几个,creater和consumer内部用循环处理,

这样就能看出效果了。

复制代码

复制代码

void * creator(void * arg)
{
    int i = 0;
    while(i<300)
    {

        i++;
        cout << "creator add lock" << endl;
        pthread_mutex_lock(&mutex);

        count ++;

        cout << "in creator count is : " << count << endl;

        if(count > 0)
        {

            pthread_cond_signal(&cond);
        }

    
        cout << "creator release lock" << endl;
    
        pthread_mutex_unlock(&mutex);

    }

    return NULL;

}





void * consumer(void * arg)
{
    int i = 0;
    while(i < 100)
    {
        
        i++;
        cout << "consumer add lock" << endl;

        pthread_mutex_lock(&mutex);

        if(count <= 0)
        {
            cout << "begin wait" << endl;
            pthread_cond_wait(&cond,&mutex);
            cout << "end wait" << endl;
        }

        count --;

        cout << "in consumer count is " << count << endl;

        pthread_mutex_unlock(&mutex);

        cout << "consumer release lock" << endl;
    }
    
    return NULL;
    
}


int main()
{
     pthread_t createthread[2],consumethread[3];

     for(int i = 0; i < 3; i++)
     {
        pthread_create(&consumethread[i], NULL, consumer, NULL);
     }
     
     for(int i = 0; i < 2; i++)
     {
        pthread_create(&createthread[i], NULL, creator, NULL);
         }
     
     for(int i = 0; i < 2; i++)
      {
        pthread_join(createthread[i], NULL);
         }

     for(int i = 0; i < 3; i++)
     {
         pthread_join(consumethread[i], NULL);
     }

    
    return 0;

}

==============================================================================================================

接下来讲解使用while和if判断线程执行条件是否成立的区别。一般来说,在多线程资源竞争的时候,在一个使用资源的线程里面(消费者)判断资源是否可用,不可用便调用pthread_cond_wait,在另一个线程里面(生产者)如果判断资源可用的话,则调用pthread_cond_signal发送一个资源可用信号。但是在wait成功之后,资源就一定可以被使用么,答案是否定的,如果同时有两个或者两个以上的线程正在等待此资源,wait返回后,资源可能已经被使用了,在这种情况下,应该使用:

while(resource == FALSE)

      pthread_cond_wait(&cond, &mutex);

如果之后一个消费者,那么使用if就可以了。解释一下原因,分解pthread_cond_wait的动作为以下几步:

1,线程放在等待队列上,解锁

2,等待 pthread_cond_signal或者pthread_cond_broadcast信号之后去竞争锁

3,若竞争到互斥索则加锁。

上面讲到,有可能多个线程在等待这个资源可用的信号,信号发出后只有一个资源可用,但是有A,B两个线程都在等待,B比较速度快,获得互斥锁,然后加锁,消耗资源,然后解锁,之后A获得互斥锁,但他回去发现资源已经被使用了,它便有两个选择,一个是去访问不存在的资源,另一个就是继续等待,那么继续等待下去的条件就是使用while,要不然使用if的话pthread_cond_wait返回后,就会顺序执行下去。

    下面来讲一下:pthread_cond_wait和pthread_cond_singal是怎样配对使用的:

     等待线程:

     pthread_cond_wait前要先加锁
     pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活
     pthread_cond_wait被激活后会再自动加锁
     激活线程:
     加锁(和等待线程用同一个锁)
     pthread_cond_signal发送信号(阶跃信号前最好判断有无等待线程)
     解锁
     激活线程的上面三个操作在运行时间上都在等待线程的pthread_cond_wait函数内部。

发布了171 篇原创文章 · 获赞 573 · 访问量 327万+

猜你喜欢

转载自blog.csdn.net/gtkknd/article/details/104251248