-
条件变量(condition variable)是利用共享的变量进行線程之间同步的一种机制典型的场景包括生产者-消费者模型,线程池实现等 对条件变量的使用包括两个动作: 1) 线程等待某个条件, 条件為真则继续执行,条件为假则将自己挂起(避免busy 2) 线程执行某些处理之后条件成立;则通知等待该条件的线程继续执行。
函数说明: (1) Condition_wait():调用時当前线程立即进入睡眠状态,同时互斥变量mutex解锁(这两步操作是原子的不可分割),以便其它线程能进入临界区修改变量 (2) Condition_signal(): 线程调用此函数後,除了当前线程继续往下执行以外; 操作系统同时做如下动作:从condition_wait()中进入睡眠的线程中选一个线程唤醒 同时被唤醒的线程试图锁(lock)住互斥量mutex, 当成功锁住后,线程就从condition_wait()中成功返回了 2. 函数接口
原先调用condition_wait的函数也可能会返回。此时线程被唤醒了但是条件并不满足,这个时候洳果不对条件进行检查而往下执行就可能会导致后续的处理出现错误。 虚假唤醒在linux的多处理器系统中/在程序接收到信号时可能回发生茬Windows系统和JAVA虚拟机上也存在。在系统设计时应该可以避免虚假唤醒但是这会影响条件变量的执行效率,而既然通过while循环就能避免虚假唤醒慥成的错误因此程序的逻辑就变成了while循环的情况。 注意:即使是虚假唤醒的情况线程也是在成功锁住mutex后才能从condition_wait()中返回。即使存在多个線程被虚假唤醒但是也只能是一个线程一个线程的顺序执行,也即:lock(mutex) unlock(mutext)顺序当等待线程被唤醒时,它试图锁住mutex,但是如果此时mutex还未解锁則线程又进入睡眠,mutex成功解锁后此线程在再次被唤醒并锁住mutex,从而从condition_wait()中返回 可以看到,按照(2)的顺序对等待线程可能会发生2次的上下攵切换,严重影响性能因此在后来的实现中,对(2)的情况如果线程被唤醒但是不能锁住mutex,则线程被转移(morphing)到互斥量mutex的等待队列中,避免了上丅文的切换造成的开销 morphing 编程时,推荐采用(1)的顺序解锁和发唤醒信号而Java编程只能按照(2)的顺序,否则发生异常!! 在SUSv3的规范中(pthread),指明了这两種顺序不管采用哪种其实现效果都是一样的。