课程咨询 :13623629309

太原PHP培训 > 达内新闻 > 太原php培训机构:Linux 环境多线程编程基础设施
  • 太原php培训机构:Linux 环境多线程编程基础设施

    发布:太原PHP培训      来源:伯乐在线      时间:2016-08-03

  • 本文介绍多线程环境下并行编程的基础设施。主要包括:

    volatile

    __thread

    Memory Barrier

    __sync_synchronize

    volatile

    编译器有时候为了优化性能,会将一些变量的值缓存到寄存器中,因此如果编译器发现该变量的值没有改变的话,将从寄存器里读出该值,这样可以避免内存访问。

    但是这种做法有时候会有问题。如果该变量确实(以某种很难检测的方式)被修改呢?那岂不是读到错的值?是的。在多线程情况下,问题更为突出:当某个线程对一个内存单元进行修改后,其他线程如果从寄存器里读取该变量可能读到老值,未更新的值,错误的值,不新鲜的值。

    如何防止这样错误的“优化”?方法就是给变量加上volatile修饰。

    太原达内php培训

    OK,毕竟volatile不是完美的,它也在某种程度上限制了优化。有时候是不是有这样的需求:我要你立即实时读取数据的时候,你就访问内存,别优化;否则,你该优化还是优化你的。能做到吗?

    不加volatile修饰,那么就做不到前面一点。加了volatile,后面这一方面就无从谈起,怎么办?伤脑筋。

    其实我们可以这样:

    太原达内php培训班

    需要实时读取i的值时候,就调用ACCESS_ONCE(i),否则直接使用i即可。

    这个技巧,我是从《Is parallel programming hard?》上学到的。

    听起来都很好?然而险象环生:volatile常被误用,很多人往往不知道或者忽略它的两个特点:在C/C++语言里,volatile不保证原子性;使用volatile不应该对它有任何Memory Barrier的期待。

    第一点比较好理解,对于第二点,我们来看一个很经典的例子:

    太原php培训班

    线程B中,虽然is_ready有volatile修饰,但是这里的volatile不提供任何Memory Barrier,因此12行和13行可能被乱序执行,is_ready = 1被执行,而message还未被正确设置,导致线程A读到错误的值。

    这意味着,在多线程中使用volatile需要非常谨慎、小心。

    __thread

    __thread是gcc内置的用于多线程编程的基础设施。用__thread修饰的变量,每个线程都拥有一份实体,相互独立,互不干扰。举个例子:

    太原达内

    需要注意的是:

    1,__thread可以修饰全局变量、函数的静态变量,但是无法修饰函数的局部变量。

    2,被__thread修饰的变量只能在编译期初始化,且只能通过常量表达式来初始化。

    Memory Barrier

    为了优化,现代编译器和CPU可能会乱序执行指令。例如:

    太原php

    CPU乱序执行后,第4行语句和第5行语句的执行顺序可能变为先b=10然后再a=b+3

    有些人可能会说,那结果不就不对了吗?b为10,a为13?可是正确结果应该是a为5啊。

    哦,这里说的是语句的执行,对应的汇编指令不是简单的mov b,10和mov b,a+3。

    生成的汇编代码可能是:

    太原达内

    这并不奇怪,为了优化性能,有时候确实可以这么做。但是在多线程并行编程中,有时候乱序就会出问题。

    一个最典型的例子是用锁保护临界区。如果临界区的代码被拉到加锁前或者释放锁之后执行,那么将导致不明确的结果,往往让人不开心的结果。

    还有,比如随意将读数据和写数据乱序,那么本来是先读后写,变成先写后读就导致后面读到了脏的数据。因此,Memory Barrier就是用来防止乱序执行的。具体说来,Memory Barrier包括三种:

    1,acquire barrier。acquire barrier之后的指令不能也不会被拉到该acquire barrier之前执行。

    2,release barrier。release barrier之前的指令不能也不会被拉到该release barrier之后执行。

    3,full barrier。以上两种的合集。

    所以,很容易知道,加锁,也就是lock对应acquire barrier;释放锁,也就是unlock对应release barrier。哦,那么full barrier呢?

    __sync_synchronize

    __sync_synchronize就是一种full barrier。

    达内时代科技集团致力于培养面向电信和金融领域JavaC++C#/.Net3G/Android3G/IOSPHP、嵌入式、软件测试、UID、网络营销、网络工程、会计、UEDwebUnity3D、大数据、童程童美等17大方向中高端软件人才课程与少儿教育课程。选择太原达内培训,不再孤军奋战,轻轻松松做IT高薪白领。太原达内培训带领有明确目标的学子迈向成功之路!想找工作的求职者可以加QQ3373924515(太原达内就业服务部)咨询了解。

上一篇:太原php培训:20个为前端开发者准备的文档和指南--(3)

下一篇:第十届达内英才添翼校企合作高峰论坛在成都召开

最新开班日期  |  更多

php高级开发名企定制班(剩2个名额)

php高级开发名企定制班(剩2个名额)

开班日期:12-30

php高级开发周末班(剩5个名额)

php高级开发周末班(剩5个名额)

开班日期:12-30

php高级开发免费试听(剩5个名额)

php高级开发免费试听(剩5个名额)

开班日期:12-30

更多高级开发工程师精品班

更多高级开发工程师精品班

开班日期:12-30

  • 地址:山西省太原市小店区学府街长治路高新国际A座24层
  • 课程培训电话:13623629309     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56

    在线客服系统