Windows几种线程同步方法介绍

发表于:2013-2-07 09:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:啊汉    来源:51Testing软件测试网采编

分享:

  系统中的所有线程都要访问系统资源,一个线程霸占某个资源,其他需要该资源的线程就不能完成自己的任务;另外如一个线程在读取某块内存中的数据,而另一个线程又正在修改这块内存的值,这同样不是我们想要的,所以线程之间必须要有一套自己的规则,不然就凌乱了。线程之间需要通信,如A线程霸占某个B线程需要的资源X,在A占用期间,B线程只能等待,或处于挂起状态,当A线程用完资源X后,系统会告诉线程B,资源X可以用了,或是将处于挂起状态的线程B唤醒,然后线程B就获得对资源X的控制权,其他想用资源X的线程就得经历B刚才的遭遇。当多个线程同时需要某个资源时必须遵守下面两个规则:

  1、多个线程“同时”访问资源,不能破坏资源的完整性。

  2、一个线程需要通知其他线程某项任务已经完成。

  原子访问:Interlocked系列函数。多线程编程大部分情况与原子访问有关,即一个线程在访问某个资源时,确保没有其他线程能访问该资源。

  增量函数InterlockedExchangeAdd结构如下:

InterlockedExchangeAdd(
    unsigned long volatile *Addend,//被增量变量的地址
    unsigned long Value//增量值
)

  Volatile表示每次都成内存中读取数据,而不会从高速缓存中读取数据,如一个全局变量,在一个多线程函数中被修改,在多核CPU中,这个变量可能在多个CPU的高速缓存中都有副本,如果不用volatile修饰,那么可能会因为优化的原因,CPU不会读内存中的数据,而是直接从高速缓存中读取数据,在这种情况下,很可能这个值已经被修改了,这样CPU读取到的不是最新的数据,程序肯定会出错,用volatile修饰后,这个变量的所有高速缓存就会失效,就不会出现这种问题。在多线程编程中volatile作用非常大,效率也最高。但他就是只能修饰单个变量,不能修饰代码段。

  InterlockedExchangeAdd执行的速度是非常快的,只需要占用几个CPU周期。用InterlockedExchangeAdd来修改某个变量的值,好像有点大材小用了,因为用Volatile就足够了,简单迅速。但在实现旋转锁时InterlockedExchange就非常有用。旋转锁的代码大致如下:

bool sourceIsUse=false;
        void fun()
        {
            //一直等待直到资源可用
            while(InterlockedExchange(&sourceIsUse,true)==true)
            {
                Sleep(0);
            }
            //访问资源的操作
            ......

            //资源用好了,打开锁,让其他等待的资源访问
            InterlockedExchange(&sourceIsUse,false);
        }

  InterlockedExchange:将第一个参数的值修改成第二个参数的值,返回第一个参数原来的值。在第一个线程就来的时候,它顺利的闯过了While循环,并上了锁,导致while始终为true,后来的线程就一直在while里面打转,当前面的线程用完之后,他就会把锁打开,然后新来的线程就可以跳出while循环,并上锁(在等待时一直在上锁),开锁独占资源了,新来的线程又开始等待。就像大厦前门的旋转门,一拨人进去之后,后面的人就只能在外面等,等里面的人出去之后,后面的人也就可以进去了,周而复始。

  高速缓存行。当CPU从内存中读取一个字节时,它并不是真的只读一个字节,而是读取一个高速缓存行,一个高速缓存行可能是32个字节、64个字节或是128个字节,它始终读取的字节数是32的整数倍,这样CPU就不用非常频繁的读取内存,从而提高程序的性能,当CPU访问某块内存是它会访问这块内存旁边的内存的概率是非常大的,于是就一起读了。更多关于数据对齐的信息请看我的文章《数据对齐》。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号