欢迎登陆真网站,您的到来是我们的荣幸。 登陆 注册 忘记密码? ☆设为首页 △加入收藏
欢迎加入真幸福QQ群
电脑知识: 基础知识 网络技术 操作系统 办公软件 电脑维修 电脑安全 windows7 windows8 windows10 服务器教程 平板电脑 视频播放教程 网络应用 互联网 工具软件 浏览器教程 QQ技巧 输入法教程 影视制作 YY教程 wps教程 word教程 Excel教程 PowerPoint
云南西双版纳特产小花糯玉米真空包装


linux软件开机自启动
家庭局域网常见故障分析
什么是操作系统?
操作系统有哪些类型
如何在企业笔记本电脑上建立移动安全策略
思科交换机如何限制BT下载?
需要IP地址和MAC地址的几点原因
思科交换机图文设置扩展ACL的配置与应用技巧
TD-LTE和FDD LTE谁更快?
win7中制作ubuntu 1210启动盘
Linux多线程之同步
【 来源:网络 】【 点击:3 】 【 发布时间:2017_03_03 08:59:59 】

引言

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待条件变量的条件成立而挂起(此时不再占用cpu);另一个线程使条件成立(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

函数原型

1. 定义条件变量

#include <pthread.h>/* 定义两个条件变量 */pthread_cond_t cond_pro, cond_con;

2. 初始化和销毁条件变量

#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 *cond);
/* 初始化条件变量 */pthread_cond_init(&cond_pro, NULL);pthread_cond_init(&cond_con, NULL);/* 销毁条件变量 */pthread_cond_destroy(&cond_pro);pthread_cond_destroy(&cond_pro);

3. 等待和激发条件

#include <pthread.h>int pthread_cond_wait(pthread_cond_t *restrict cond,  pthread_mutex_t *restrict mutex);int pthread_cond_broadcast(pthread_cond_t *cond);int pthread_cond_signal(pthread_cond_t *cond);
/* 等待条件 *//* 注意:pthread_cond_wait为阻塞函数。解开锁,再等待。等条件满足时,需要抢到锁,才可以被唤醒*/    pthread_cond_wait(&cond_pro,&mutex); /* 激发条件 *//* 所有因为不满足条件的线程都会阻塞在条件变量cond_pro中的一个队列中 *//* 以广播方式,通知所有被阻塞的所有线程 */pthread_cond_broadcast(&cond_pro);/* 以signal方式,只通知排在最前面的线程 */pthread_cond_signal(&cond_pro);

代码

/*************************************************************************    > File Name: my_con.c    > Author: KrisChou    > Mail:zhoujx0219@163.com     > Created Time: Tue 26 Aug 2014 10:24:29 AM CST ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <unistd.h>#define CELL 10#define FLORE 0int i = 0; /* 所有线程共享的全局变量,此处假定至多递增至10,最小减到0 */pthread_mutex_t mutex;              /* 定义互斥锁 */pthread_cond_t cond_pro, cond_con;  /* 定义两个条件变量 *//* 生产者线程 */void* pro_handler(void *arg){    pthread_detach(pthread_self());   /* 由系统回收线程资源,而非主线程回收资源 ,此类情况主线程是个服务器,永久不会退出 */        while(1)    {        pthread_mutex_lock(&mutex);        while(i >= CELL)        {            pthread_cond_wait(&cond_pro,&mutex);             /* continue是轮询,此处是阻塞 */            /* 把锁放开再等 ,第一个参数是结构体指针,其中有成员存放被阻塞的函数 */            /*不占cpu*/            /* 不满足条件时才会等 ,需要别人告诉它,才能唤醒它*//* 当它返回时,锁也要回来了*/        }        i++;        if(i == 1)        {            /* 由空到不空,唤醒消费者 */            pthread_cond_signal(&cond_con);    /*不会立马signal被阻塞的消费者线程,因为其还要等锁抢回来*/        }        printf("add i: %d /n", i);        pthread_mutex_unlock(&mutex);        sleep(rand() % 5 + 1);    }}/* 消费者线程 */void* con_handler(void *arg){    pthread_detach(pthread_self());    while(1)    {        pthread_mutex_lock(&mutex);        while(i <= FLORE)        {            pthread_cond_wait(&cond_cno,&mutex);        }        i--;        if(i == 9) /* 由满到不满,要告诉生产者,以便将其唤醒 *//*此处,直接signal也可以,我们是为了更加精确*/        {            pthread_cond_signal(&cond_pro);        }        printf("con i: %d /n", i);        pthread_mutex_unlock(&mutex);        sleep(rand() % 5 + 1);    }}int main(int argc, char *argv[]) // exe +num -num{    srand(getpid());    int con_cnt, pro_cnt;    pro_cnt = atoi(argv[1]);    con_cnt = atoi(argv[2]);    pthread_mutex_init(&mutex,NULL);    pthread_cond_init(&cond_pro,NULL);    pthread_cond_init(&cond_con,NULL);    pthread_t *arr = (pthread_t*)calloc(con_cnt + pro_cnt , sizeof(pthread_t));    int index = 0;    while(pro_cnt > 0)    {        pthread_create(arr + index, NULL, pro_handler, NULL);        index++;        pro_cnt--;    }    while(con_cnt > 0)    {        pthread_create(arr + index, NULL, con_handler, NULL);        index++;        con_cnt--;    }    while(1);    pthread_mutex_destroy(&mutex);    pthread_cond_destroy(&cond_pro);    pthread_cond_destroy(&cond_con);    return 0;}

注意

无论是在生产者线程,还是在消费者线程中。标记黄色部分的判断条件必须用while。以生产者线程举例,当i>=CELL时,也就是i满时,此时执行pthread_cond_wait(&cond_cno,&mutex); 该生产者线程被挂起。必须等到消费者线程pthread_cond_signal(&cond_pro); 将其唤醒。但是消费者将其signal还不够,被挂其的生产者线程必须重新拿到锁,才可以被激活。但是,由于在消费者signal的同时,生产者并不能立即抢到锁,所以此时可能i值又改变变为大于等于10了。因此必须用while。不然可能导致i>10。

本网站由川南居提供技术支持,fkzxf版权所有 浙ICP备12031891号
淳安分站 淳安分站