Windows线程同步【5】条件变量(Condition Variable)

一、引言

假设有一个任务,由我和张三共同完成。张三把寄来的文稿初步审阅后放入一个队列,我负责将这个队列中的文稿进行审批,决定刊登与否。张三审阅一份文稿需要15分钟,我处理一个文稿需要2分钟。

如果将张三和我看作两个线程,那么我们共享一个队列的数据。按照一般的多线程思路,他每隔一段时间往队列中放入数据,我每隔一段时间检查一下队列中是否有数据,若有,则处理之。

若我们按照上面的方式工作,则大部分的时间,我只是在干等着,所以,这是一种比较低效的方式。

但换一种方式之后,情况就好很多了。他每把一个文稿放入队列,就检查一下队列中的文稿数量是否达到20,若达到,则通知我来处理。我来进行处理之后,由于我的处理速度更快,所以一段时间之后,队列会变空,我便离开。这样,我就可以把时间更有效率的利用起来,例如,利用空余的时间打扫卫生、整理文件或做一些其他的事情。

有些时候,我们不应让一个线程“忙等”,而是应让它休眠(sleep)以节省计算机资源,直到一个条件满足之后,再继续工作。

利用条件变量就可以达到上述目的。

条件变量有两个状态:成立不成立

二、初始化

在使用条件变量之前,需要定义一个CONDITION_VARIABLE类型的变量:

CONDITION_VARIABLE cv;

与条件变量有关的函数有5个;

InitializeConditionVariable
SleepConditionVariableCS
SleepConditionVariableSRW
WakeConditionVariable
WakeAllConditionVariable

对条件变量,不能在代码中直接进行读、写,所有的操作必须通过上述函数进行

条件变量在使用之前必须进行初始化,方法是:

InitializeConditionVariable(&cv);

在程序不再需要条件变量时,不需要手动销毁它。

三、等待

等待条件变量可以用SleepConditionVariableCS或SleepConditionVariableSRW函数。

SleepConditionVariableCS(&cv, &cs, dwTimeout);

第一个参数是条件变量的指针,第二个参数是临界区(CRITICAL_SECTION)指针,第三个参数是超时,单位:毫秒。

这个函数的作用是,解锁cs并等待cv成立,函数返回之后,会将cs重新锁上,并将cs设为不成立。在等待期间,当前线程会休眠,直到它被唤醒(见后面介绍的用来唤醒的函数)。

SleepConditionVariableSRW用法与之类似,详见这里:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686304.aspx

四、通知(唤醒)

WakeConditionVariable(&cv);

用WakeConditionVariable将cv的状态设为成立,并唤醒正在等待cv的那些线程中的一个。

WakeAllConditionVariable(&cv);

用WakeAllConditionVariable将cv的状态设为成立,并唤醒所有的正在等待cv的那些线程。

时间: 2024-09-29 20:37:16

Windows线程同步【5】条件变量(Condition Variable)的相关文章

线程同步之——条件变量

一.生产消费模型:我们可以用条件变量来实现线程之间的同步,利用一个生产消费模型具体的实现同步.生产消费模型可以简单地称为3,2,1模型(即3种关系,2个对象,1个场所),同时还需注意以下3点: 1.生产者和消费者是同步互斥关系: 2.生产者和生产者是互斥关系: 3.消费者和消费者是互斥关系. 二.条件变量的理解:线程A需要等某个条件成才能继续往下执,现在这个条件不成,线程A就阻塞等待,线程B在执过程中使这个条件成了,就唤醒线程A继续执. 在pthread库中通过条件变量(Condition Va

Linux程序设计学习笔记----多线程编程之线程同步之条件变量

转载请注明出处:http://blog.csdn.net/suool/article/details/38582521. 基本概念与原理 互斥锁能够解决资源的互斥访问,但是在某些情况下,互斥并不能解决问题,比如两个线程需 要互斥的处理各自的操作,但是一个线程的操作仅仅存在一种条件成立的情况下执行,一旦错过不可再重现,由于线程间相互争夺cpu资源,因此在条件成立的时候,该线程不一定争夺到cpu而错过,导致永远得不到执行..... 因此需要某个机制来解决此问题,更重要的是,线程仅仅只有一种情况需要执

线程—同步之条件变量

条件变量:允许线程阻塞等待另一个线程发送信号唤醒.条件变量被用来阻塞一个线程,当条件不满足时,线程解开相应的互斥锁并等待条件发生变化.如果其他线程改变了条件变量,并且使用条件变量换型一个或多个正被此条件变量阻塞的线程.这些线程将重新锁定互斥锁并重新测试条件是否满足.条件变量被用来进行线程间的同步. thread 1 con = threading.Condition()    #创建条件变量 while True: do something con.acquire()    #获取锁 con.n

条件变量(Condition Variable)详解

转载于:http://blog.csdn.net/erickhuang1989/article/details/8754357 条件变量(Condtion Variable)是在多线程程序中用来实现"等待->唤醒"逻辑常用的方法.举个简单的例子,应用程序A中包含两个线程t1和t2.t1需要在bool变量test_cond为true时才能继续执行,而test_cond的值是由t2来改变的,这种情况下,如何来写程序呢?可供选择的方案有两种: 第一种是t1定时的去轮询变量test_co

线程同步(条件变量、信号量)以及死锁

死锁:指两个或两个以上进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待现象,若无外力作用,它们都将无法继续推进下去. 例:交叉死锁:线程1获得了锁1,线程2获得了锁2,此时线程1调用lock想获得锁2,需挂起等待线程2释放锁2,而线程2也想获得锁1,也需挂起等待线程1释放锁1,此时两个线程都挂起等待 产生死锁的四个必要条件: (1):互斥条件(一个资源每次只能被一个进程或线程使用) (2):请求与保持条件(一个进程或线程因请求资源而阻塞时,对已获得的资源不释放) (3):不剥夺条件(此

3线程同步:条件变量

1 条件变量 条件变量给多个线程提供了一个汇合的场所. 依赖的头文件 #include<pthread.h> 函数声明 定义分配条件变量 pthread_cond_t cond =PTHREAD_COND_INITIALIZER; int pthread_cond_init(pthread_cond_t*restrict cond, const pthread_condattr_t *restrict attr); 名称: pthread_cond_init 功能: initialize co

线程同步之条件变量使用手记

由来: 最近一直在想怎么高效率的在IO线程接收到数据时通知逻辑线程(基于线程池)工作的问题,像网络编程的服务器模型的一些模型都需要用到这个实现,下面我这里简单的罗列一个多线程的网络服务器模型 半同步/半异步(half-sync/half-async): 许多餐厅使用 半同步/半异步 模式的变体.例如,餐厅常常雇佣一个领班负责迎接顾客,并在餐厅繁忙时留意给顾客安排桌位,为等待就餐的顾客按序排队是必要的.领班由所有顾客"共享",不能被任何特定顾客占用太多时间.当顾客在一张桌子入坐后,有一个

linux线程同步(2)-条件变量

一.概述                                                    上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保护临界区.条件变量是多线程间可以通过它来告知其他线程某个状态发生了改变,让等待在这个条件变量的线程继续执行.通俗一点来讲:设置一个条件变量让线程1等待在一个临界区的前面,当其他线程给这个变量执行通知操作时,线程1才会被唤醒,继续向下执行. 条件变量总是和互斥量一起使用,互斥量保护着条件变量,防止多个

四十一、Linux 线程——线程同步之条件变量

41.1 概念 41.1.1 条件变量的介绍 互斥锁的缺点是它只有两种状态:锁定和非锁定 条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足 条件变量内部是一个等待队列,放置等待的线程,线程在条件变量上等待和通知,互斥锁用来保护等待队列(对等待队列上锁),条件变量通常和互斥锁一起使用 条件变量允许线程等待特定条件发生,当条件不满足时,线程通常先进入阻塞状态,等待条件发生变化.一旦其它的某个线程改变了条件,可唤醒一个或多个阻塞的线程 具体的判断条件还需用户给出 条件变量数据类

四十二、Linux 线程——线程同步之条件变量之线程状态转换

42.1 线程状态转换 42.1.1 状态转换图 42.1.2 一个线程计算,多个线程获取的案例 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <unistd.h> 5 6 /** 两个线程定义的共享资源 */ 7 typedef struct { 8 int res; 9 int counter; ///< 用于统计获取结果线程的数量 10 p