浅析linux下的条件变量
来源:互联网 发布:excel数据分析方法五种 编辑:程序博客网 时间:2024/06/18 14:08
一.条件变量
条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量可以通过允许线程阻塞和等待另一个线程发送信号来弥补互斥锁的不足,所以互斥锁和条件变量通常一起使用。
当条件满足的时候,线程通常解锁并等待该条件发生变化,一旦另一个线程修改了环境变量,就会通知相应的环境变量唤醒一个或者多个被这个条件变量阻塞的线程。这些被唤醒的线程将重新上锁,并测试条件是否满足。一般来说条件变量被用于线程间的同步;当条件不满足的时候,允许其中的一个执行流挂起和等待。
条件变量中常用的API:
1).条件变量类型为:pthread_cond_t ,类似互斥变量,条件变量的初始化有两种方式:
静态:pthread_cond_t mycon=PTHREAD_COND_INITIALIZER;
动态:通过调用pthread_cond_init函数,函数原型为:
静态:pthread_cond_t mycon=PTHREAD_COND_INITIALIZER;
cond:环境变量.
attr:条件变量属性.
成功返回0,失败返回错误码.
2).条件变量摧毁函数:pthread_cond_destroy(&mycond);
int pthread_cond_destroy(pthread_cond_t *cond);
成功返回0,失败返回错误码.
摧毁所指定的条件变量,同时将会释放所给它分配的资源。调用该函数的进程也并不等待在参数所指定的条件变量上。
3).条件变量等待函数。pthread_cond_wait(&mycond,&mylock);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
cond:条件变量
mutex:互斥锁
pthread_cond_wait和pthread_cond_timedwait的区别:
pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于,如果达到或是超过所引用的参数*abstime,它将结束并返回错误ETIME.
timespec
typedef struct timespec { time_t tv_sec; //!> 秒 long tv_nsex; //!> 毫秒 }timespec_t;
当时间超过之前预设定的时会返回错误.
4).条件变量通知函数:pthread_cond_signal和pthread_cond_broadcast
int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);
pthread_cond_signal和pthread_cond_broadcast的区别:
pthread_cond_signal:只唤醒一个在相同条件变量中阻塞的线程将会被唤醒
pthread_cond_broadcast:唤醒等待队列中的所有线程
二.一个关于互斥锁和条件变量的栗子
栗子:用互斥锁和条件变量的概念实现一个简单的生产者和消费者的模型。
生产者和消费者模型:
1).满足互斥与同步条件,用互斥锁和条件变量实现
2).多个生产者和消费者:生产者和生产者属于互斥关系;生产者和消费者属于互斥和同步关系;消费者和消费者属于竞争关系,需要互斥锁
3).生产者和消费者模型中存在如下几种关系和角色:3种关系,2种角色,1种交换媒介(一般是一段内存)
下例以单生产者和单消费者,交换媒介为链表实现的生产者消费者模型
procon.c#include<stdio.h>#include<stdlib.h>#include<assert.h>#include<pthread.h>typedef struct LinkNode{int data;struct LinkNode *next;}Node;pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;pthread_cond_t mycond=PTHREAD_COND_INITIALIZER;Node *CreatNode(int data){Node *NewNode=(Node *)malloc(sizeof(Node));if(NULL == NewNode){perror("malloc");return NULL;}NewNode->data=data;NewNode->next=NULL;return NewNode;}void InitLink(Node **head){*head=CreatNode(0);}int IsEmpty(Node *head){assert(head);if(head->next)return 0; //not emptyelsereturn 1; //empty}void PushFront(Node *head,int data){assert(head);Node *NewNode=CreatNode(data);NewNode->next=head->next;head->next=NewNode;}void PopFront(Node *head,int *data){assert(data);assert(head);if(IsEmpty(head)){printf("empty link\n");return ;}Node *del=head->next;*data=del->data;head->next=del->next;free(del);del=NULL;}void DisplayLink(Node *head){assert(head);Node *cur=head->next;while(cur){printf("%d ",cur->data);cur=cur->next;}printf("\n");}void DestroyLink(Node *head){int data=0;assert(head);while(!IsEmpty(head)){PopFront(head,&data);}free(head);}void *product_run(void *arg){int data=0;Node *head=(Node *)arg;while(1){usleep(100000);data=rand()%1000;pthread_mutex_lock(&mylock);PushFront(head,data);pthread_mutex_unlock(&mylock);pthread_cond_signal(&mycond);printf("product is done,data=%d\n",data);}}void *consumer_run(void *arg){int data=0;Node *head=(Node *)arg;while(1){pthread_mutex_lock(&mylock);while(IsEmpty(head)){pthread_cond_wait(&mycond,&mylock);}PopFront(head,&data);pthread_mutex_unlock(&mylock);printf("consumer is done,data=%d\n",data);}}void testprocon(){Node *head=NULL;InitLink(&head);pthread_t tid1;pthread_t tid2;pthread_create(&tid1,NULL,product_run,(void *)head);pthread_create(&tid2,NULL,consumer_run,(void *)head);pthread_join(tid1,NULL);pthread_join(tid2,NULL);DestroyLink(head);pthread_mutex_destroy(&mylock);pthread_cond_destroy(&mycond);}int main(){testprocon();return 0;}Makefileprocon:procon.cgcc -o $@ $^ -lpthread.PHONY:cleanclean:rm -f procon
总结:
条件变量用在某个线程需要在某种条件才去保护它将要操作的临界区的情况下,从而避免了线程不断轮询检查该条件是否成立而降低效率的情况,这是实现了效率提高。
希望对读者有帮助吧~~~~
- 浅析linux下的条件变量
- 浅析linux下的条件变量
- Linux 下条件变量
- Linux多线程编程下的条件变量
- linux下条件变量的使用
- linux下实现同步的---条件变量
- linux下条件变量的实验研究
- 浅析互斥锁与条件变量的使用
- LINUX下的条件变量与互斥锁的搭配使用
- linux下多线程中条件变量的用法
- linux下多线程中条件变量的用法
- Linux系统下的多线程编程-条件变量&信号量
- Linux操作系统下的多线程编程详细解析----条件变量
- Linux下多线程之条件变量的个人理解
- linux下的互斥锁,条件变量和信号量
- Linux操作系统下的多线程编程详细解析----条件变量
- Linux操作系统下的多线程编程详细解析----条件变量
- linux下的线程同步互斥量+条件变量
- Django Rest Framework - 异常 、返回值处理 与 分页实现
- sys/cdefs.h: No such file or directory
- 多态
- 64-bit Tips
- 【Spring 核心】AOP 面向切面编程
- 浅析linux下的条件变量
- 深入剖析volatile关键字
- 算法原理 第四章
- 混淆矩阵
- 中文版LoadRunner11:分析结果数据不全解决办法
- Android应用组件之ContentProvider
- WebApp方式集成5+ sdk
- ubuntu16.04 + GTX1060 + Cuda 8.0 + Zed SDK 环境搭建
- HTTP Header 详解