• <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>

            C++ Programmer's Cookbook

            {C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

            C++多線程(三)

            多線程同步之Critical Sections(功能與Mutex相同,保證某一時刻只有一個線程能夠訪問共享資源,但是不是內核對象,所以訪問速度要比Mutex快,但是增沒有等待超時的功能,所以有可能會導致死鎖,使用時可以根據實際的情況選擇其一

            一 Critical Sections

            1) 因為Critical Sections不是內核對象,所以只能用來統一進程內線程間的同步,不能用來多個不同進程間的線程的同步。

            2) 如果在Critical Sections中間突然程序crash或是exit而沒有調用LeaveCriticalSection,則結果是改線程所對應的內核不能被釋放,該線程成為死線程。

            3) 要比其他的內核對象的速度要快。

            二 使用CriticalSections的簡單實例,Stack在push的時候可以分為3個步驟,看下面的代碼,但是如果在第2步后此線程中斷切換到其他的線程,其他的線程push后再返回執行時,此線程繼續執行,這樣有可能剛才其他線程push就會被覆蓋了,在stack里找不到了。(下面的代碼在debug下使用了CriticalSection,release下可能有問題)

            #include <windows.h>
            #include 
            <process.h>
            #include 
            <stdio.h>
            /////////////////////////////////////////////
            //stack:
            struct Node 
            {
                
            struct Node *next; 
                
            int data; 
            }

            struct Stack 

                
            struct Node *head; 
            #ifdef _DEBUG
                CRITICAL_SECTION critical_sec; 
            #endif

                Stack()
                
            {
                    head 
            = NULL;
            #ifdef _DEBUG
                    InitializeCriticalSection(
            &critical_sec);
            #endif
                }

                
            ~Stack()
                
            {        
                    
            if(head != NULL)        
                    
            {
                        
            if(NULL == head->next)
                        
            {                
                            delete head;
                            head 
            = NULL;
                        }

                        
            else
                        
            {
                            Node 
            *= head;
                            Node 
            *= head->next;

                            
            while(q != NULL)
                            
            {                    
                                delete p;
                                p 
            = q;
                                q 
            = q->next;
                            }
            ;                
                            delete p;
                            p 
            = NULL;
                        }
                
                    }

            #ifdef _DEBUG
                    DeleteCriticalSection(
            &critical_sec);
            #endif
                }

                
            void Push (int num) 
                

                    
            //enter critical section, add a new node and then     
            #ifdef _DEBUG
                    EnterCriticalSection (
            &critical_sec);
            #endif
                    Node 
            * node = new Node();
                    node
            ->next = head;
                    node
            ->data = num;
                    head 
            = node;  
                    printf(
            "Stack:%d\n",num);
                    
            //leave critical section 
            #ifdef _DEBUG
                    LeaveCriticalSection (
            &critical_sec);
            #endif
                }
             
                
            int Pop () 
                

            #ifdef _DEBUG
                    EnterCriticalSection (
            &critical_sec);
            #endif
                    
            int result = 0;
                    
            if(head!= NULL)
                    
            {
                        result 
            = head->data;
                        
            if(head->next != NULL)
                        
            {
                            Node 
            *temp = head->next; 
                            delete head;
                            head 
            = temp;
                        }

                        
            else
                            head 
            = NULL;
                    }
                
            #ifdef _DEBUG
                    LeaveCriticalSection (
            &critical_sec); 
            #endif
                    
            return result; 
                }

            }
            ;

            //////////////////////////////////////////////////////
            //test:
            unsigned  __stdcall Thread1(void * pVoid)
            {
                Stack 
            *stack = ((Stack*)pVoid);
                
            for(int i = 200; i<220;++i)
                
            {
                    stack
            ->Push(i);
                }

                
            return 1;        
            }

            unsigned __stdcall Thread2(
            void *pVoid)
            {
                Stack 
            *stack = ((Stack*)pVoid);
                
            for(int i = 0; i<20++i)
                
            {
                    stack
            ->Push(i);        
                }

                
            return 1;
            }

            int main()

                Stack stack;
                stack.Push(
            1000);
                stack.Push(
            1000);

                HANDLE   hth1;
                unsigned  uiThread1ID;

                hth1 
            = (HANDLE)_beginthreadex( NULL,         // security
                    0,            // stack size
                    Thread1,
                    (
            void*)&stack,           // arg list
                    CREATE_SUSPENDED,  // so we can later call ResumeThread()
                    &uiThread1ID );

                
            if ( hth1 == 0 )
                    printf(
            "Failed to create thread 1\n");

                DWORD   dwExitCode;

                GetExitCodeThread( hth1, 
            &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
                printf( "initial thread 1 exit code = %u\n", dwExitCode );



                HANDLE   hth2;
                unsigned  uiThread2ID;

                hth2 
            = (HANDLE)_beginthreadex( NULL,         // security
                    0,            // stack size
                    Thread2,
                    (
            void*)&stack,           // arg list
                    CREATE_SUSPENDED,  // so we can later call ResumeThread()
                    &uiThread2ID );

                
            if ( hth2 == 0 )
                    printf(
            "Failed to create thread 2\n");

                GetExitCodeThread( hth2, 
            &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
                printf( "initial thread 2 exit code = %u\n", dwExitCode );  

                ResumeThread( hth1 );   
                ResumeThread( hth2 );

                WaitForSingleObject( hth1, INFINITE );
                WaitForSingleObject( hth2, INFINITE );

                GetExitCodeThread( hth1, 
            &dwExitCode );
                printf( 
            "thread 1 exited with code %u\n", dwExitCode );

                GetExitCodeThread( hth2, 
            &dwExitCode );
                printf( 
            "thread 2 exited with code %u\n", dwExitCode );

                CloseHandle( hth1 );
                CloseHandle( hth2 );    

                printf(
            "Primary thread terminating.\n");
            }


            三 對Critical Section的封裝:
            //////////////////////////////////////////////////////
            // 方法一: Lock中的CritSect成員變量必須是引用類型。
            class CritSect
            {
            public:
                friend 
            class Lock;
                CritSect() 
            { InitializeCriticalSection(&_critSection); }
                
            ~CritSect() { DeleteCriticalSection(&_critSection); }
            private:
                
            void Acquire(){EnterCriticalSection(&_critSection);}
                
            void Release(){LeaveCriticalSection(&_critSection);}

                CRITICAL_SECTION _critSection;
            }
            ;

            class Lock
            {
            public:
                 Lock(CritSect
            & critSect):_critSect(critSect) {    _critSect.Acquire(); }
                 
            ~Lock(){_critSect.Release();}
            private:
                CritSect
            & _critSect;
            }
            ;

            //////////////////////////////////////////////////////
            //方法二:
            // MT-exclusive lock
            class CLock {
            public:
                CLock()             
            { InitializeCriticalSection (&m_criticalSection); }
                
            void Lock ()        { EnterCriticalSection      (&m_criticalSection); }
                
            void Unlock ()      { LeaveCriticalSection      (&m_criticalSection); }
                
            virtual ~CLock()    { DeleteCriticalSection     (&m_criticalSection); }
            private:
                CRITICAL_SECTION                    m_criticalSection;
            }
            ;


            // Scoped MT-exclusive lock
            class CScopedLocker {
            public:
                CScopedLocker (CLock 
            * t) : m_lock (t)      { m_lock->Lock();   }
                
            ~CScopedLocker()                            { m_lock->Unlock(); }
            private:
                CLock 
            *                             m_lock;
            }
            ;


            對上面的2中封裝的調用都比較簡單,都是只有2行代碼。
            CritSect sect;
            Lock lock(sect);

            CLock t;
            CSCopedLocker st(&t);

            下面的對封裝的測試代碼,保證了對g_n全局變量在線程1操作結束后線程2才可以操作。(下面的代碼因為對全局變量同步,所以需要申明含有CRITICAL_SECTION的類為全局)

            #include<windows.h>
            #include
            <iostream>
            using namespace std;

            //////////////////////////////////////////////////////
            // ·½·¨Ò»£º

            class CritSect
            {
            public:
                friend 
            class Lock;
                CritSect() 
            { InitializeCriticalSection(&_critSection); }
                
            ~CritSect() { DeleteCriticalSection(&_critSection); }
            private:
                
            void Acquire(){EnterCriticalSection(&_critSection);}
                
            void Release(){LeaveCriticalSection(&_critSection);}

                CRITICAL_SECTION _critSection;
            }
            ;

            class Lock
            {
            public:
                 Lock(CritSect
            & critSect):_critSect(critSect) {    _critSect.Acquire(); }
                 
            ~Lock(){_critSect.Release();}
            private:
                CritSect
            & _critSect;
            }
            ;

            //////////////////////////////////////////////////////
            //·½·¨¶þ£º

            // MT-exclusive lock
            class CLock {
            public:
                CLock()             
            { InitializeCriticalSection (&m_criticalSection); }
                
            void Lock ()        { EnterCriticalSection      (&m_criticalSection); }
                
            void Unlock ()      { LeaveCriticalSection      (&m_criticalSection); }
                
            virtual ~CLock()    { DeleteCriticalSection     (&m_criticalSection); }
            private:
                CRITICAL_SECTION                    m_criticalSection;
            }
            ;


            // Scoped MT-exclusive lock
            class CScopedLocker {
            public:
                CScopedLocker (CLock 
            * t) : m_lock (t)      { m_lock->Lock();   }
                
            ~CScopedLocker()                            { m_lock->Unlock(); }
            private:
                CLock 
            *                             m_lock;
            }
            ;

            // ¶ÔÈ«¾ÖµÄ±äÁ¿£¬Ê¹ÓÃCritical Section
            // Declare the global variable
            static int  g_n;
            CritSect sect;
            //CLock t;



            ////////Thread One Function///////////////////
            UINT ThreadOne(LPVOID lParam)
            {
                
                Lock 
            lock(sect);    
                
            //CScopedLocker st(&t);
                
                
            for(int i=0;i<100;i++)
                
            {
                    g_n
            ++;
                    cout 
            << "Thread 1: " << g_n << "\n";
                }
                    
                
            // return the thread
                return 0;
            }



            ////////Thread Two Function///////////////////
            UINT ThreadTwo(LPVOID lParam)
            {


                Lock 
            lock(sect);
                
            //CScopedLocker st(&t);

                
            for(int i=300;i<400;i++)
                
            {
                    g_n
            ++;
                    cout 
            << "Thread 2: "<< g_n << "\n";
                }


                
            // return the thread
                return 0;
            }



            int main()
            {

                
            // Create the array of Handle
                HANDLE hThrd[2];    
                
            //Thread ID's
                DWORD IDThread1, IDThread2;


                
            // Create thredas use CreateThread function with NULL Security
                hThrd[0= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadOne,(LPVOID)NULL,0,&IDThread1);       
                hThrd[
            1= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadTwo,(LPVOID)NULL,0,&IDThread2); 

                
            // Wait for the main thread 
                WaitForMultipleObjects(2,hThrd,TRUE,INFINITE);
                
                
            return 0;
            }


            四 API列表:
            Critical-section function Description
            DeleteCriticalSection Releases all resources used by an unowned critical section object.
            EnterCriticalSection Waits for ownership of the specified critical section object.
            InitializeCriticalSection Initializes a critical section object.
            InitializeCriticalSectionAndSpinCount Initializes a critical section object and sets the spin count for the critical section.
            InitializeCriticalSectionEx Initializes a critical section object with a spin count and optional flags.
            LeaveCriticalSection Releases ownership of the specified critical section object.
            SetCriticalSectionSpinCount Sets the spin count for the specified critical section.
            TryEnterCriticalSection Attempts to enter a critical section without blocking.

            posted on 2007-07-25 18:04 夢在天涯 閱讀(6105) 評論(0)  編輯 收藏 引用 所屬分類: CPlusPlus

            公告

            EMail:itech001#126.com

            導航

            統計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1804607
            • 排名 - 5

            最新評論

            閱讀排行榜

            亚洲午夜久久影院| 久久精品免费大片国产大片| 久久综合亚洲色一区二区三区| 波多野结衣久久一区二区| 99久久免费国产精精品| 香蕉久久一区二区不卡无毒影院| 久久久青草青青亚洲国产免观| 亚洲精品成人网久久久久久| 国内精品久久久久影院优 | 午夜天堂av天堂久久久| 久久久久综合网久久| 亚洲精品无码久久久久去q | 亚洲国产精品无码久久SM| 欧美777精品久久久久网| 久久99久国产麻精品66| 久久久久国产一区二区| 97久久精品无码一区二区天美| 国内精品伊人久久久久777| 久久午夜福利电影| 国内精品久久久久久久97牛牛| 性欧美大战久久久久久久久| 久久本道综合久久伊人| 国产精品久久久天天影视香蕉| 久久精品国产精品亚洲精品| 久久精品国产亚洲AV无码麻豆| 久久久久亚洲AV片无码下载蜜桃| 欧美亚洲国产精品久久久久| 伊人色综合久久天天| 国产精品亚洲美女久久久| 久久精品国产亚洲AV高清热| 无码人妻久久一区二区三区蜜桃 | 久久99精品国产麻豆宅宅| 久久青青草原精品国产| 久久精品国产日本波多野结衣| 久久综合色之久久综合| 久久久久久久综合日本| 久久er国产精品免费观看8| 久久国产精品视频| 久久精品国产亚洲Aⅴ香蕉| 波多野结衣久久精品| 久久久老熟女一区二区三区|