【C/C++多线程编程之八】pthread条件变量

多线程编程之条件变量

     Pthread POSIX threads 的简称,是POSIX线程标准

        互斥机制,包括互斥量C/C++多线程编程之六】pthread互斥量,信号量C/C++多线程编程之七】pthread信号量,互斥能很好的处理共享资源访问的协调问题,是多线程同步必不可少的机制。互斥机制也有其缺陷,当线程在等待共享资源满足某个条件,互斥机制下,必须不断地加锁和解锁,其间查询共享资源是否满足条件,这将带来巨大的消耗。

        此时,需要新的机制来解决这个问题。

       1.条件变量机制:

        条件变量机制弥补了互斥机制的缺陷,允许一个线程向另一个线程发送信号(这意味着共享资源某种条件满足时,可以通过某个线程发信号的方式通知等待的线程),允许阻塞等待线程(当线程等待共享资源某个条件时,可让该线程阻塞,等待其他线程发送信号通知)。

        条件变量机制在处理等待共享资源满足某个条件问题时,具有非常高的效率,且空间消耗相比互斥机制也有优势。

    

        2.条件变量与互斥量:

       条件变量机制,所有等待一个条件变量的线程会形成一个队列,这个队列显然是全局的共享队列。当线程进入等待状态,将线程添加到队列就需要使用互斥量,防止多个线程同时使用pthread_cond_wait,在调用pthread_cond_wait前加锁互斥量,进入阻塞前解锁互斥量。这也解释了pthread_cond_wait函数参数需要互斥量。

        3.条件变量基本函数:

扫描二维码关注公众号,回复: 2449242 查看本文章

         #include <semaphore.h>

初始化条件变量:

        int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr) ;

        该函数第一个参数为条件变量指针,第二个参数为条件变量属性指针(一般设为NULL)。该函数按照条件变量属性对条件变量进程初始化。

无条件等待:

        int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

        该函数第一个参数为条件变量指针,第二个为互斥量指针。该函数调用前,需本线程加锁互斥量,加锁状态的时间内函数完成线程加入等待队列操作 ,线程进入等待前函数解锁互斥量。在满足条件离开pthread_cond_wait函数之前重新获得互斥量并加锁,因此,本线程之后需要再次解锁互斥量。

通知一个线程:

        int pthread_cond_signal(pthread_cond_t *cond);

        该函数的参数为条件变量指针。该函数向队列第一个等待线程发送信号,解除这个线程的阻塞状态。

通知所有线程:

        int pthread_cond_broadcast(pthread_cond_t *cond);

        该函数的参数为条件变量指针。该函数想队列所有等待线程发送信号,解除这些线程的阻塞状态。

销毁条件变量:

        int pthread_cond_destroy(pthread_cond_t *cond);

        该函数销毁条件变量。

        4.牛刀小试

         共享资源i,线程1i进行无限加1操作,并输出所有非5倍数的i值。当i的值为5的倍数时,通过条件变量机制,通知线程2,线程2输出此时的i值。

 

 

 

 

#include "pthread.h"

#include "sched.h"

#include "semaphore.h"

#include "stdio.h"

#include "windows.h"

 

#pragma comment(lib, "pthreadVC2.lib")     //必须加上这句

 

pthread_t t1;           //pthread_t变量t1,用于获取线程1的ID

pthread_t t2;           //pthread_t变量t2,用于获取线程2的ID

      

pthread_mutex_t mutex;

pthread_cond_t cond;

 

int i=0;                //共享资源

 

void * child1(void *arg)

{

while(1)

{

pthread_mutex_lock(&mutex);

 

i++;

if(i%5==0)

{

pthread_cond_signal(&cond);

}

else

{

printf("我是线程  1  打印的数都非5的倍数:  %d \n",i);

}

 

pthread_mutex_unlock(&mutex);

Sleep(1000);

}

}     

 

void *child2(void *arg)

{

    while(1)

{

pthread_mutex_lock(&mutex);

 

printf("code before pthread_con_wait");

 

pthread_cond_wait(&cond,&mutex);       //获得信号之前,会重新获得互斥锁

 

printf("我是线程  2  打印5的倍数:  %d \n",i);

 

pthread_mutex_unlock(&mutex);          //需要在此处释放互斥锁

 

Sleep(1000);

}

}

 

int main(void)

{        

pthread_cond_init(&cond,NULL);

pthread_mutex_init(&mutex,NULL);

 

pthread_create(&t1,NULL,child1,NULL);

pthread_create(&t2,NULL,child2,NULL);

 

Sleep(100000000);

 

return 0;

}

 

来自 <https://blog.csdn.net/lovecodeless/article/details/24929273>

猜你喜欢

转载自blog.csdn.net/zcc1229936385/article/details/81231130