Windows和Linux对决(线程间同步)
1.1 Windows线程同步
1.1.1 关键代码区Critical Section
所谓“关键代码区”,相信大家看名字也能理解个大概了。首先:它很关键,第二:它是代码区。之所以关键,当然目的就是每次只能一个线程能够进入;既然是代码区,那就是只能在一组拥有同样代码的线程中用。
那什么情况下会用到关键代码区呢?当然是要保护多个线程都会用到的东西了,说到这里,想必你已经猜到了:全局变量和静态变量。
1.1.2 互斥Mutex
互斥看起来和关键代码区是一样的,都是每次都是只允许一个线程使用。但互斥和关键代码区相比,具有如下特点:
对比点
|
关键代码区
|
互斥
|
备注
|
名字
|
无名字
|
有名字
|
NA
|
跨进程
|
不能跨进程
|
可以跨进程
|
因为有名字,所以可以跨进程
|
访问模式
|
没有超时
|
可以超时
|
NA
|
死锁问题
|
线程挂了其它线程就只能傻等了
|
线程挂了,操作系统会通知其它线程
|
NA
|
运行环境
|
用户区
|
内核区
|
所以关键代码区性能要高一些。
|
1.1.3 信号量Semaphore
信号量本质上就是一个计数器,当计数器大于0时就意味着被保护的对象可用。每次申请计数器就减1,释放就加1.
信号量和互斥体相比,一个最明显的差别就在于互斥体每次只能有一个线程进行访问,而信号量可以有多个线程进行访问。
看到这里,大家可能都像我开始一样存在这样的问题:如果将信号量最大值设置为1,那么不就是相当于互斥量了吗?
看起来是一样的,而且在有些系统上也确实是这样的,据说是互斥体底层就是信号量来实现的,或者干脆就没有互斥体(例如传统UNIX),但在有的系统上还是有差别的,差别在于:申请和释放是否要同一个线程完成,Windows就是这种形式。互斥体要求同一线程来申请和释放,而信号量就可以由不同的线程申请和释放(但是我很难想象这样做有什么好处,难倒要给一个线程集中获取信号量,再来通知另外的线程工作?)。
1.1.4 事件Event
事件本质上是一个系统信号,即:发生了某件事情后,发一个信号给其它关心这件事情的线程。
从事件的本质上来看,事件不是为了资源保护的,而是为了线程间通知用的。举个简单的例子:Socket接收完一个消息后,将其放入队列,然后需要通知消息处理线程进行处理。
大家想想,如果没有事件通知会怎么样呢?那接收线程只能设一个定时器或者循环,定时甚至循环去查询队列中是否有消息,这种定时和循环处理是对系统性能的极大浪费,所以,有了事件后,就不用这么浪费了。
1.2 Linux线程同步
介绍完Windows,Linux介绍就很方便了,就像上一篇博文提到的一样,Windows和Linux其实很多地方相似,线程同步也不例外。
1.2.1 关键代码区???
不好意思,Linux没有这个东东。
1.2.2 互斥Mutex
Linux和Windows是一样的,这里就不详细介绍了,需要注意的是传统UNIX并没有互斥这个东东,传统UNIX的互斥是通过二元信号量(即最大值为1)来实现的。
1.2.3 信号量Semaphore
需要注意的是Linux中信号量有两种:一种是内核POSIX标准的信号量,一种是用户态的传统UNIX IPC信号量。两者的差别如下:
对比点
|
POSIX Semaphore
|
IPC Semaphore
|
备注
|
控制者
|
内核
|
用户
|
IPC Semaphore可以通过semctrl函数修改对外表现。
|
权限控制
|
不允许修改
|
用户可修改
|
NA
|
性能
|
优于IPC
|
劣于POSIX
|
NA
|
范围
|
进程级
|
系统级
|
如果进程退出时忘记关闭,POSIX会自动释放。
|
POSIX信号量和Windows的信号量是一样的。
1.2.4 条件变量Conditions
看到这个名字有点莫名其妙,条件变量和线程同步有什么关系呢?
但其实是Linux(或者是POSIX)的名字取得不好才导致我们很难理解,本质上条件变量就是Windows的事件,作用也是一样的。唉,如果Linux或者POSIX不想和Windows同名,改成叫“通知”也能让我们这些小虾多省点脑力啊:)
1.2.5 信号Signal
类似于“共享内存”也是一种进程间通信的方式一样,我把信号也列进来作为线程同步的一种,因为本质上信号不是为了线程间同步而设计的,但我们可以利用其作为线程同步来使用。
如何使用信号呢?既然信号本身就是一种通知(还记得上面我建议将“条件变量”建议改名为什么吗?),那我们就按照通知来使用了,例如:A做完了某事,发一个信号给B,B收到后开始启动做另外一件事。
请注意:和“条件变量”不同的是,条件变量支持广播机制,而信号只能是点对点,因此实际使用中应该还是“条件变量”方便一些。当然如果是传统UNIX,那就只能利用信号来进行通知了。
===============================================================================
注:看我的博客的朋友可能会发现一个现象,我几乎从来不介绍详细的函数或者API,而基本上都在“归纳、总结、对比”。这是我个人的一个风格或者理解吧,我认为函数或者API用的时候查一下就可以了,而在分析和设计的时候,关键是要知道有哪些东西可以给我们用,而且要知道我们具体究竟应该用哪个,因此在平时就必须多归纳、总结、对比,而不是背住各种函数和API。
==========================未完待续===============================
分享到:
相关推荐
2007年"教育部-英特尔精品课程建设项目" 2008年"教育部-IBM精品课程建设项目" CELL处理器、Intel Core 2处理器的并行计算基本原理 ...PCAM并行程序设计方法、程序性能分析与优化基本策略 BSP并行程序模型
作者都是长期供职于Intel公司的资深软件工程师和结构师,书中融入了他们自己丰富的软硬件开发经验,可以为面向多核体系结构进行并行程序设计的开发人员提供巨大的帮助。不论对从未接触过并行程序设计的开发人员,...
多核处理器下并行程序设计探析.pdf
作者都是长期供职于Intel公司的资深软件工程师和结构师,书中融入了他们自己丰富的软硬件开发经验,可以为面向多核体系结构进行并行程序设计的开发人员提供巨大的帮助。不论对从未接触过并行程序设计的开发人员,...
《基于多核的并行程序设计》大学课程课件。
此资源包含了多核程序设计实验的基本代码,包括课本习题的代码
然后结合Windows平台与Linux平台及多核厂家提供的软件调优工具,详细介绍了多核程序设计与调优方法。除此以外,还详细介绍了OpenMP与MPI利用多核平台进行并行程序设计的方法等。 本书涵盖了多核软件设计各个方面,...
基于多核处理器的高清实时MPEG-2——H.264转码器设计.pdf
一个初学者觉得有用的入门级文档。内容有多线程并行和趋势展望
多核时代下的并行编程(下)-NILabVIEW网络讲坛第三季flv,仅仅凭借自动多线程的特性,还无法充分地利用多核优势,本集中,工程师将详细讲解如何在LabVIEW中实现多核性能的充分利用,包括任务并行化、数据并行化以及...
Intel多核程序设计竞赛第二题:零和(串行代码)Intel多核程序设计竞赛第二题:零和(串行代码)Intel多核程序设计竞赛第二题:零和(串行代码)Intel多核程序设计竞赛第二题:零和(串行代码)Intel多核程序设计...
多核计算与程序设计
基于多核CPU的并行计算设计.pdf
基于多核CPU的并行程序在指控系统中的应用.pdf
对多核编程和优化技术的现状进行全面的研究和分析,在论述如何将串行程序并行化的同时,分析现今主流的一些多核并行编程工具和模型。在此基础上,进一步讨论了在多核编程过程中影响程序性能的因素,并阐述了软硬件...
多核(64核)系统的并行FFT运算程序
详细介绍多核程序设计理论以及理论模型,并提供详细编程实例
多核处理器 和并行升序设计, 课件和一些实例源代码
该资源整理方式很独特,是利用结构图的形式进行...该资源是对多核并行计算的总结,里面包含并行和并发,各种锁机制,同步机制,互斥机制,并发数据结构等内容的总结。有了该图,学习多处理器编程,会有很大的指导效果
第一个分太高了要50,过分,通过阅读和学习,读者可以掌握基于多种平台(多核、多处理器、集群和GPU等),利用多项技术(Matlab并行计算工具箱、多线程MEX文件、OpenMP和GPU等),学习理解Matlab并行程序设计的原理、...