与条件变量相关API
        条件变量是线程另一可用的同步机制。条件变量给多个线程提供了一个会合的场所。条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定的条件发生。

        条件本身是由互斥量保护的。线程在改变条件状态前必须首先锁住互斥量,其他线程在获得互斥量之前不会察觉到这种改变,因为必须锁定互斥量以后才能计算条件。

        条件变量使用之前必须首先初始化,pthread_cond_t数据类型代表的条件变量可以用两种方式进行初始化,可以把常量        PTHREAD_COND_INITIALIZER赋给静态分配的条件变量,但是如果条件变量是动态分配的,可以使用pthread_cond_destroy函数对条件变量进行去除初始化(deinitialize)。
1. 创建及销毁条件变量

#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t*restrict cond);
// 返回:若成功返回0,否则返回错误编号

除非需要创建一个非默认属性的条件变量,否则pthread_cont_init函数的attr参数可以设置为NULL。cond参数是条件也要进行定义和初始化
2. 等待

#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);//这个是立即返回
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);//这个是等待一段时间后返回
// 返回:若成功返回0,否则返回错误编号

        pthread_cond_wait等待条件变为真。如果在给定的时间内条件不能满足,那么会生成一个代表一个出错码的返回变量。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传给函数。函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个操作都是原子操作。这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道,这样线程就不会错过条件的任何变化。pthread_cond_wait返回时,互斥量再次被锁住。

        pthread_cond_timedwait函数的工作方式与pthread_cond_wait函数类似,只是多了一个timeout。timeout指定了等待的时间,它是通过timespec结构指定。
3. 触发

#include <pthread.h>
int pthread_cond_signal(pthread_cond_t*restrict    cond);
int pthread_cond_broadcast(pthread_cond_t *restrict cond);
// 返回:若成功返回0,否则返回错误编号

这两个函数可以用于通知线程条件已经满足。pthread_cond_signal函数将唤醒等待该条件的某个线程,而pthread_cond_broadcast函数将唤醒等待该条件的所有进程。

注意一定要在改变条件状态以后再给线程发信号。
  
代码示例

#include<stdio.h>
#include<pthread.h>
#include <stdlib.h>
//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);

int g_data=0;//

pthread_mutex_t mutex;
pthread_cond_t cond;

void*func1(void *arg)
{

        static cnt=0;
        printf("t1 :%ld thread is created\n",(unsigned long)pthread_self());
        printf("t1:param is %d\n",*((int*)arg));
        while(1){
                pthread_cond_wait(&cond,&mutex);
                printf("t1 over==============================\n");
                printf("t1 :%d\n",g_data);
                g_data=0;
                sleep(1);
                if(cnt++==10){
                        exit(1);
                }

        }

}

void*func2(void *arg)
{
        printf("t2 :%ld thread is created\n",(unsigned long)pthread_self());
printf("t2:param is %d\n",*((int*)arg));
        while(1){
                printf("t2 printf is %d\n",g_data);
                pthread_mutex_lock(&mutex);
                g_data++;
                if(g_data==3){
                        pthread_cond_signal(&cond);
                }
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
        pthread_mutex_unlock(&mutex);
}

int main()
{
        int ret;
        int param=100;
        pthread_t t1;
        pthread_t t2;
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);
        ret=pthread_create(&t1,NULL,func1,(void*)&param);
        if(ret==0){
        //      printf("main:create t1 success\n");
        }
        ret=pthread_create(&t2,NULL,func2,(void*)&param);
        if(ret==0){
//      printf("main:create t2 success\n");
        }
//      printf("main : %ld \n",(unsigned long)pthread_self());
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        return 0;
}
//其中func1中的cnt是测试用的
以下代码可以用试:
CLC@Embed_Learn:~/xiancheng$ gcc demo8.c -lpthread -odemo8
CLC@Embed_Learn:~/xiancheng$ vi text1.c
CLC@Embed_Learn:~/xiancheng$ ./a.out 10 >>test.ret.txt &(其中>>表示将运行的结果追加到test.ret.txt中     &表示在后台运行)
[1] 21313(这是进程的ID号)

初始化

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
//静态初始化
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
//动态初始化

参考博文:https://www.cnblogs.com/xiehongfeng100/p/4620852.html

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐