• <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>
            對于多線程編程,很多人概念不清,寫代碼的時候要么是處處加鎖,影響性能不說,還容易莫名其妙的死鎖,還有人對多線程敬而遠之。

            所以學習多線程編程最重要的不是學習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.局部變量局部使用是安全的
            為什么?因為每個thread 都有自己的運行堆棧,而局部變量是生存在堆棧中,大家不干擾。
            所以代碼1
            int local1;
            ++local1;
            是安全的

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

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

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

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

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

            7.在32機器上,4字節整形一次assign是原子的
            比如
            i =10; //thread1
            i=4; //thread2
            不會導致i的值處于未知狀態,要么是10要么是4


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

            Feedback

            # re: 什么代碼才是線程安全的  回復  更多評論   

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

            認識深刻嗎?
            對于Meyer Singleton,你有沒有實際監測過,我只是通過<Effective C++>中條款3了解到Meyer Singleton。可是對于上面的“可能造成多次初始化對象”,能不能做更加詳細的闡述,可不可以進一步舉例示范?

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

            # re: 什么代碼才是線程安全的  回復  更多評論   

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

            上面又說:
            ++這個操作其實分為兩部,一個是讀,另外一個是寫
            mov ecx,global
            add ecx,1
            mov global,ecx
            當為多線程時,MyClass構造函數可能會被調用多次:舉個例子


            class MyClass2
            {
            public:
            MyClass2()
            {
            m++;
            //如果去掉sleep,則第二次調用函數func()時不會再進入構造函數,所以要線程安全,要防止代碼同時進入這里.
            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: 什么代碼才是線程安全的  回復  更多評論   

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

            # re: 什么代碼才是線程安全的  回復  更多評論   

            2008-02-25 18:03 by 愛飯盒
            呵呵,剛才代碼貼的不對,多線程的沒貼出來,在多線程時能體現出來這點,單線程體現不出來.
            91精品国产91热久久久久福利 | 久久亚洲熟女cc98cm| 香蕉99久久国产综合精品宅男自 | 一级女性全黄久久生活片免费 | 久久人人超碰精品CAOPOREN| 国产成人综合久久精品红| 国产精品毛片久久久久久久| 精品久久久久中文字| 亚洲精品国产美女久久久| 久久久国产精华液| 精品无码久久久久国产| 亚洲精品美女久久久久99小说 | 亚洲国产精品无码久久| 久久国产一片免费观看| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 久久亚洲AV无码精品色午夜麻豆| 国产精品岛国久久久久| 亚洲精品午夜国产VA久久成人 | 国产一久久香蕉国产线看观看| 久久久久人妻一区精品| 狠狠狠色丁香婷婷综合久久五月| 久久久一本精品99久久精品88| 久久精品亚洲欧美日韩久久| 国产精品久久久亚洲| 国内精品综合久久久40p| 亚洲国产一成久久精品国产成人综合 | 久久午夜综合久久| 久久香蕉综合色一综合色88| 欧美丰满熟妇BBB久久久| 一本久道久久综合狠狠爱| 国产精品久久久久久久app| 日产久久强奸免费的看| 免费一级欧美大片久久网| 精品综合久久久久久88小说| 91久久精品国产免费直播| 亚洲狠狠久久综合一区77777| 久久99亚洲网美利坚合众国| 久久99国产精品尤物| 九九精品99久久久香蕉| 97久久国产亚洲精品超碰热| 久久久久久久人妻无码中文字幕爆|