Linux多线程编程入门-同步机制-条件变量

原创 2013年12月04日 14:56:21

Linux平台上触发条件变量则自动复位。

条件变量的置位和复位有两种常用模型:第一种模型是当条件变量置位(signaled)以后,如果当前没有线程在等待,其状态会保持为置位(signaled),直到有等待的线程进入被触发,其状态才会变为复位(unsignaled),这种模型的采用以 Windows 平台上的 Auto-set Event 为代表。其状态变化如图 1 所示:



第二种模型则是 Linux 平台的 Pthread 所采用的模型,当条件变量置位(signaled)以后,即使当前没有任何线程在等待,其状态也会恢复为复位(unsignaled)状态。其状态变化如图 2 所示:



具体来说,Linux 平台上 Pthread 下的条件变量状态变化模型是这样工作的:调用 pthread_cond_signal() 释放被条件阻塞的线程时,无论存不存在被阻塞的线程,条件都将被重新复位,下一个被条件阻塞的线程将不受影响。而对于 Windows,当调用 SetEvent 触发 Auto-reset 的 Event 条件时,如果没有被条件阻塞的线程,那么条件将维持在触发状态,直到有新的线程被条件阻塞并被释放为止。

这种差异性对于那些熟悉 Windows 平台上的条件变量状态模型而要开发 Linux 平台上多线程的程序员来说可能会造成意想不到的尴尬结果。试想要实现一个旅客坐出租车的程序:旅客在路边等出租车,调用条件等待。出租车来了,将触发条件,旅客停止等待并上车。一个出租车只能搭载一波乘客,于是我们使用单一触发的条件变量。这个实现逻辑在第一个模型下即使出租车先到,也不会有什么问题,其过程如下。


采用linux条件变量模型的出租车实例流程。


采用windows条件变量模型的出租车实例流程。



代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <iostream>
using namespace std;
pthread_mutex_t taxiMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t taxiCond = PTHREAD_COND_INITIALIZER;
void * traveler_arrive(void * name) {
	cout << "Traveler: " << (char*)name << " needs a taxi now " << endl;
	pthread_mutex_lock(&taxiMutex);
	pthread_cond_wait(&taxiCond, &taxiMutex);
	pthread_mutex_unlock(&taxiMutex);
	cout << "Traveler: " << (char*)name << " now got a taxi." << endl;
	pthread_exit((void*)0);
}

void * taxi_arrive(void * name) {
	cout << " Taxi " << (char*)name << " arrives." << endl;
	pthread_cond_signal(&taxiCond);
	pthread_exit((void*)0);
}

int main() 
{	
	pthread_t thread;
	pthread_attr_t threadAttr;
	pthread_attr_init(&threadAttr);

	pthread_create(&thread, &threadAttr, taxi_arrive, (void*)(" Jack "));
	sleep(1);
	pthread_create(&thread, &threadAttr, traveler_arrive, (void*)(" Susan "));
	sleep(1);
	pthread_create(&thread, &threadAttr, taxi_arrive, (void*)(" Mike "));
	sleep(1);
	return 0;
}


运行结果如下:

Taxi Jack arrives. 
    Traveler Susan needs a taxi now! 
    Taxi Mike arrives. 
    Traveler Susan now got a taxi.



参考链接:

Linux 的多线程编程的高效开发经验http://www.ibm.com/developerworks/cn/linux/l-cn-mthreadps/

linux 多线程编程 互斥锁与条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待 “ 条件变量的条件成立” 而挂起,另一个线程使 “条件成立 ”(给出条件成立信号),为了防止竞争,条件变量的使用总...
  • kennyrose
  • kennyrose
  • 2012年05月26日 15:28
  • 1774

Linux线程间同步机制_条件变量

有时看网上的博客自己会纳闷,进程间的同步机制和线程间的同步机制分别是什么?     其实进程之间是不用同步机制的,因为进程之间资源不共享,不需要同步机制来对所谓的临界资源进行保护,所以通常我们只讨论...
  • xixihaha331
  • xixihaha331
  • 2016年05月23日 16:34
  • 862

Linux多线程编程入门-同步机制-信号量

int sem_init(sem_t *sem, int pshared, unsigned int value); pshared:控制信号量的类型,0表示这个信号量是当前进程的局部信号量,否则,这...
  • a304672343
  • a304672343
  • 2013年12月03日 11:59
  • 527

linux多线程编程入门-同步机制-互斥量

所谓同步,并不是日常用语中的同时进行的意思。这里的同步是指如何阻止同步进行的意思。 互斥量,又称互斥锁,它允许程序员锁住某个对象,使得每次只能有一个线程访问它。为了控制对关键代码的访问,必须在进入这段...
  • a304672343
  • a304672343
  • 2013年12月03日 10:40
  • 653

嵌入式 Linux C 多线程编程 互斥锁与条件变量

一、互斥锁   互斥量从本质上说就是一把锁, 提供对共享资源的保护访问。     1. 初始化:     在Linux下, 线程的互斥量数据类型是pthread_mutex_t. 在使用前, 要对它进...
  • skdkjxy
  • skdkjxy
  • 2013年12月02日 14:57
  • 895

Linux线程同步机制的几种方法总结与对比

线程同步机制的几种方法总结与对比 需要线程同步的原因: 当有多个线程同时访问一个共享内存里面的变量时,有时会出现一个线程正在修改该变量的值,而其他的线程正在读取数据,可能就会导致错误。   实...
  • u010853261
  • u010853261
  • 2014年10月28日 14:46
  • 1443

Linux 同步机制:条件变量

条件变量的优势条件变量提供了一种线程间的通知机制,达到条件唤醒对应线程,配合互斥量,可以解决多线程中大多数的同步问题。需要信号量的解决问题的基本都可以用条件变量加互斥量解决。由于信号量使用起来容易出错...
  • thisinnocence
  • thisinnocence
  • 2017年01月13日 00:15
  • 269

Linux多线程编程(三)-----生产者与消费者(条件变量,信号量)

Linux多线程编程(一):http://blog.csdn.net/llzk_/article/details/55670172 Linux多线程编程(二):http://blog.csdn.ne...
  • LLZK_
  • LLZK_
  • 2017年02月22日 21:02
  • 1761

Linux多线程编程入门

线程基本知识\quad进程是资源管理的基本单元,而线程是系统调度的基本单元,线程是操作系统能够进行调度运算的最小单位,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制...
  • taoyanqi8932
  • taoyanqi8932
  • 2017年02月21日 17:43
  • 1220

从零学习linux多线程编程--第一篇

线程(thread)技术早在60年代就被提出,但真正应用多线程到 ***作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(process)中...
  • sunsnow2
  • sunsnow2
  • 2014年08月19日 20:59
  • 554
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux多线程编程入门-同步机制-条件变量
举报原因:
原因补充:

(最多只允许输入30个字)