• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            對(duì)于多線程編程,很多人概念不清,寫代碼的時(shí)候要么是處處加鎖,影響性能不說,還容易莫名其妙的死鎖,還有人對(duì)多線程敬而遠(yuǎn)之。

            所以學(xué)習(xí)多線程編程最重要的不是學(xué)習(xí)API,而是理解什么才是多線程安全的代碼

            從例子說起
            #include?<windows.h>
            #include?
            <process.h>

            long?global1?=?0;
            volatile?long?global2?=?0;

            class?MyClass
            {
            public:
            ????MyClass()?:?m(
            0)
            ????{
            ????????
            ++m;
            ????}

            ????
            int?fun(int?v)
            ????{
            ????????
            return?m+v;?//-----------9
            ????}

            ????
            void?set(int?v)
            ????{
            ????????m?
            =?v;???//-------------10
            ????}
            ????
            int?m;
            };

            MyClass?global_object;?
            //-------------8

            unsigned?
            int?__stdcall?thread_fun1(void?*param)
            {
            ????
            static?int?static2?=?0;
            ????
            static?MyClass?static_object;?//--------6
            ????int?local1?=?0;
            ????
            ????
            ++local1;?????//-------1
            ????++static2;????//-------2
            ????++global1;????//-------3
            ????++global2;????//-------4
            ????InterlockedIncrement(&global1);?//--------5

            ????local1?
            =?global_object.fun(local1);?//----------7

            ????global_object.
            set(local1);?//---------------11

            ????
            return?0;
            }


            unsigned?
            int?__stdcall?thread_fun2(void?*param)
            {
            ????
            ++global1;????//-------3
            ????++global2;????//-------4
            ????InterlockedIncrement(&global1);?//--------5

            ????global_object.
            set(1);?//-----------11
            ????return?0;
            }


            int?main()
            {
            ????HANDLE?thread1?
            =?(HANDLE)_beginthreadex(0,0,&thread_fun1,0,0,0);?//thread?1
            ????HANDLE?thread2?=?(HANDLE)_beginthreadex(0,0,&thread_fun1,0,0,0);?//thread?2
            ????HANDLE?thread3?=?(HANDLE)_beginthreadex(0,0,&thread_fun2,0,0,0);?//thread?3
            ????
            ????WaitForSingleObject(thread1,INFINITE);
            ????WaitForSingleObject(thread2,INFINITE);
            ????WaitForSingleObject(thread3,INFINITE);
            ????
            ????
            return?0;
            }




            1.局部變量局部使用是安全的
            為什么?因?yàn)槊總€(gè)thread 都有自己的運(yùn)行堆棧,而局部變量是生存在堆棧中,大家不干擾。
            所以代碼1
            int local1;
            ++local1;
            是安全的

            2.全局原生變量多線程讀寫是不安全的
            全局變量是在堆(heap)中
            long global1 = 0;
            ++global2;
            ++這個(gè)操作其實(shí)分為兩部,一個(gè)是讀,另外一個(gè)是寫
            ?mov???????? ecx,global
            ?add???????? ecx,1
            ?mov???????? global,ecx
            所以代碼3處是不安全的

            3.函數(shù)靜態(tài)變量多線程讀寫也是不安全的
            道理同2
            所以代碼2處也是不安全的

            4.volatile能保證全局整形變量是多線程安全的么
            不能。
            volatile僅僅是告誡compiler不要對(duì)這個(gè)變量作優(yōu)化,每次都要從memory取數(shù)值,而不是從register
            所以代碼4也不是安全

            5.InterlockedIncrement保證整型變量自增的原子性
            所以代碼5是安全的

            6.function static object的初始化是多線程安全的么
            不是。
            著名的Meyer Singleton其實(shí)不是線程安全的
            Object & getInstance()
            {?
            ???? static Object o;
            ???? return o;
            }
            可能會(huì)造成多次初始化對(duì)象
            所以代碼6處是不安全的

            7.在32機(jī)器上,4字節(jié)整形一次assign是原子的
            比如
            i =10; //thread1
            i=4; //thread2
            不會(huì)導(dǎo)致i的值處于未知狀態(tài),要么是10要么是4


            寫好多線程安全的法寶就是封裝,使數(shù)據(jù)有保護(hù)的被訪問到
            安全性:
            局部變量>成員變量>全局變量
            Posted on 2006-11-30 16:11 艾凡赫 閱讀(3044) 評(píng)論(4)  編輯 收藏 引用 所屬分類: 多線程C++

            Feedback

            # re: 什么代碼才是線程安全的  回復(fù)  更多評(píng)論   

            2008-02-25 16:28 by badboyfind
            請(qǐng)問:您對(duì)
            function static object的初始化是多線程安全的么
            不是。
            著名的Meyer Singleton其實(shí)不是線程安全的
            Object & getInstance()
            {
            static Object o;
            return o;
            }
            可能會(huì)造成多次初始化對(duì)象
            所以代碼6處是不安全的

            認(rèn)識(shí)深刻嗎?
            對(duì)于Meyer Singleton,你有沒有實(shí)際監(jiān)測(cè)過,我只是通過<Effective C++>中條款3了解到Meyer Singleton??墒菍?duì)于上面的“可能造成多次初始化對(duì)象”,能不能做更加詳細(xì)的闡述,可不可以進(jìn)一步舉例示范?

            可以回復(fù)我的郵箱: sincere_listen@163.com
            急需知道答案!

            # re: 什么代碼才是線程安全的  回復(fù)  更多評(píng)論   

            2008-02-25 17:45 by 愛飯盒
            MyClass() : m(0)
            {
            ++m;
            }
            問題出在這里;

            上面又說:
            ++這個(gè)操作其實(shí)分為兩部,一個(gè)是讀,另外一個(gè)是寫
            mov ecx,global
            add ecx,1
            mov global,ecx
            當(dāng)為多線程時(shí),MyClass構(gòu)造函數(shù)可能會(huì)被調(diào)用多次:舉個(gè)例子


            class MyClass2
            {
            public:
            MyClass2()
            {
            m++;
            //如果去掉sleep,則第二次調(diào)用函數(shù)func()時(shí)不會(huì)再進(jìn)入構(gòu)造函數(shù),所以要線程安全,要防止代碼同時(shí)進(jìn)入這里.
            sleep(10);
            cout<<"MyClass2:"<<m<<endl;
            }
            int m;
            void func(){ cout<< "func:"<<m<<endl;}
            };
            void func()
            {
            static MyClass2 o2;
            o2.func();
            }
            int main()
            {
            func();
            cout<<"################"<<endl;
            func();
            return 0;
            }

            # re: 什么代碼才是線程安全的  回復(fù)  更多評(píng)論   

            2008-02-25 17:51 by 愛飯盒
            這里對(duì)同時(shí)進(jìn)入一段代碼使用sleep()進(jìn)行放大處理,實(shí)際應(yīng)用時(shí),單單一個(gè)++m,也可能會(huì)同時(shí)多個(gè)線程訪問.只是++m不太好測(cè)試.

            # re: 什么代碼才是線程安全的  回復(fù)  更多評(píng)論   

            2008-02-25 18:03 by 愛飯盒
            呵呵,剛才代碼貼的不對(duì),多線程的沒貼出來,在多線程時(shí)能體現(xiàn)出來這點(diǎn),單線程體現(xiàn)不出來.
            久久精品国产第一区二区| 国内精品久久久久影院亚洲| 人人狠狠综合久久亚洲婷婷| 国产精品久久久久影院嫩草| 久久精品国产亚洲AV不卡| 久久亚洲AV成人无码软件 | 久久综合狠狠综合久久激情 | 99久久精品国产毛片| 午夜人妻久久久久久久久| 国产成人综合久久精品尤物| 久久综合亚洲欧美成人| 亚洲国产精品无码久久久久久曰| 久久精品午夜一区二区福利 | 亚洲色欲久久久综合网东京热 | 久久大香香蕉国产| 尹人香蕉久久99天天拍| 久久精品国产一区二区三区不卡| 久久婷婷国产综合精品| 亚洲欧美成人久久综合中文网 | 久久99国产综合精品| 久久亚洲国产最新网站| 久久久久久青草大香综合精品| 久久久免费精品re6| 久久婷婷五月综合色奶水99啪| 久久毛片免费看一区二区三区| 久久99精品国产99久久| 国产亚洲精久久久久久无码| 亚洲欧美日韩久久精品第一区| 久久受www免费人成_看片中文 | 久久久久久亚洲精品不卡| 91精品国产高清久久久久久国产嫩草| 久久夜色精品国产噜噜麻豆| 国产亚洲美女精品久久久2020| 久久免费看黄a级毛片| 国产精品久久久久久久久久影院| 久久久久亚洲国产| 久久受www免费人成_看片中文 | 欧美与黑人午夜性猛交久久久| 久久精品国产精品亚洲人人| 九九久久精品无码专区| 亚洲美日韩Av中文字幕无码久久久妻妇 |