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

            網絡服務器軟件開發/中間件開發,關注ACE/ICE/boost

            C++博客 首頁 新隨筆 聯系 聚合 管理
              152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks
            #ifndef THREAD_H
            #define THREAD_H

            #include 
            <stdio.h>//printf

            #ifdef WIN32
            #define WIN32_LEAN_AND_MEAN
            #include 
            <Windows.h>
            #define THREAD_API         DWORD WINAPI
            #else
            #include 
            <pthread.h>
            #define THREAD_API         void*          
            #endif

            class CThread
            {
            private:

            #ifdef WIN32
                HANDLE m_hThreadHandle;
                DWORD  m_dwThreadId;
            #else
                pthread_t  m_dwThreadId;
            #endif

                
            bool      m_bStopFlag;//是否已經“取消”該線程
                bool      m_bStarted;//線程已經啟動

            private:
                
            struct CThreadArg 
                
            {
                    CThread
            * m_pThread;//保存this指針
                    void*    m_pArg;//保存start成員函數里面的arg參數指針
                }
            ;

                CThreadArg
            * m_pThrArg;
            public:
                CThread();    
                
            ~CThread();
                
            int Start(void* arg = NULL);
                
            int  Wait();//成功返回0;失敗-1

                
            void Terminate(void);//強制退出

                
            void  SetStopFlag();    //協作性退出
                bool  GetStopFlag();    


                unsigned 
            int GetID(void);
                
                
            protected:    
                
            void SetThreadArg(CThreadArg* pThrArg = NULL);
                CThreadArg
            * GetThreadArg(void);

                
            virtual void Run(void* arg) = 0;//1.子類重載此函數,在run里面完成所有功能.2.子類要檢查GetStopFlag(),以配合對該線程的“停止”;或者采用強制終止Terminate()

            private:
                
            static THREAD_API Routine(void* arg);    
            }
            ;


            #endif




             下面是Thread.cpp

            #include 
            "Thread.h"

            CThread::CThread():m_dwThreadId(
            0),m_bStopFlag(false),m_bStarted(false)
            {
            #ifdef WIN32
                m_hThreadHandle 
            = NULL;
                SetThreadArg(NULL);
            #endif
            }


            CThread::
            ~CThread()
            {
            #ifdef WIN32
                
            if (m_hThreadHandle != NULL)
                
            {
                    CloseHandle(m_hThreadHandle);
                }

            #endif

                
            if (m_pThrArg != NULL)
                
            {
                    delete m_pThrArg;
                    m_pThrArg 
            = NULL;
                }

            }


            int CThread::Start(void* arg /* = NULL */)
            {
                
            if (m_bStarted)
                
            {
                    
            return 0;
                }

                
            else
                
            {
                    m_bStarted 
            = true;
                }

                
                CThreadArg 
            *pThrArg = new CThreadArg();
                pThrArg
            ->m_pArg = arg;
                pThrArg
            ->m_pThread = this;


            #ifdef WIN32        
                m_hThreadHandle 
            = CreateThread(NULL,NULL,Routine,(void*)pThrArg,NULL,&m_dwThreadId);
                
            if (m_hThreadHandle != NULL)
                
            {
                    m_pThrArg 
            = pThrArg;
                    
            return 0;
                }

                
            else
                
            {
                    delete pThrArg;
                    
            return -1;
                }


            #else
                
            int ret = pthread_create(&m_dwThreadId,NULL,Routine,(void*)pThrArg);
                
            if (ret == 0)
                
            {
                    m_pThrArg 
            = pThrArg;
                    
            return 0;
                }

                
            else
                
            {
                    delete pThrArg;
                    
            return -1;
                }
                    
            #endif        
            }


            int CThread::Wait()
            {
            #ifdef WIN32
                ::WaitForSingleObject(m_hThreadHandle,INFINITE);
                BOOL bRet 
            = CloseHandle(m_hThreadHandle);
                
            if (bRet)
                
            {
                    m_hThreadHandle 
            = NULL;
                    
            return 0;
                }

                
            else
                    
            return -1;

            #else
                
            int nRet = pthread_join(m_dwThreadId,NULL);
                
            if(nRet == 0)
                    
            return 0;
                
            else
                    
            return -1;        
            #endif        
            }


            void CThread::SetStopFlag()
            {
                m_bStopFlag 
            = true;
                
            return;
            }


            bool CThread::GetStopFlag()
            {
                
            return m_bStopFlag;
            }


            void CThread::Terminate()
            {
            #ifdef WIN32
                
            if (GetCurrentThreadId() == m_dwThreadId)
                
            {
                    ExitThread(
            0);
                    
            return;
                }

                
            else
                
            {        
                    TerminateThread(m_hThreadHandle,
            0);
                    DWORD dwRet 
            = 0;
                    GetExitCodeThread(m_hThreadHandle,
            &dwRet);
                    
                    
            while (dwRet == STILL_ACTIVE)
                    
            {
                        printf(
            "still active \n");
                        Sleep(
            100);
                        TerminateThread(m_hThreadHandle,
            0);
                        GetExitCodeThread(m_hThreadHandle,
            &dwRet);
                    }

                }

            #else
                
            if (pthread_self() == m_dwThreadId)
                
            {
                    pthread_exit(NULL);
                    
            return;
                }

                
            else
                
            {
                    pthread_cancel(m_dwThreadId);
                }

                
            #endif
                
                SetStopFlag();
                
            return;
            }


            unsigned 
            int CThread::GetID(void)
            {
                
            return (unsigned int) m_dwThreadId;
            }


            void CThread::SetThreadArg(CThreadArg* pThrArg /* = NULL */)
            {
                m_pThrArg 
            = pThrArg;
                
            return;
            }


            CThread::CThreadArg
            * CThread::GetThreadArg()
            {
                
            return m_pThrArg;
            }


            THREAD_API CThread::Routine(
            void* arg)
            {

                CThreadArg
            * pThrArg = (CThreadArg*)arg;

            #ifndef WIN32
                pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
                pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
            #endif

                pThrArg
            ->m_pThread->Run(pThrArg->m_pArg);    
                
            return NULL;
            }


             自己用的,如果你有好的想法,告訴我!
            posted on 2009-01-19 12:54 true 閱讀(2782) 評論(12)  編輯 收藏 引用 所屬分類: linux

            Feedback

            # re: 自己造的一個線程類 2009-01-19 14:13 eXile
            Win32最好不要使用CreateThread, 使用 _beginthreadex  回復  更多評論
              

            # re: 自己造的一個線程類[未登錄] 2009-01-19 20:58 true
            @eXile
            嗯,這個網上有這種說法,不過我目前主要在linux,至于win下沒那么講究。  回復  更多評論
              

            # re: 自己造的一個線程類 2009-01-21 12:38 星綻紫輝
            具體可查看《Windows核心編程》,里面講到CreateThread可能不會釋放tid線程塊,而C運行庫的_beginthreadex在內部調用了CreateThread,很好地解決了釋放問題。  回復  更多評論
              

            # re: 自己造的一個線程類 2009-02-18 18:15 陳頭
            linux下使用,竟然不能使用工廠模式,
            創建線程工廠有錯誤。原因是Run方法,郁悶  回復  更多評論
              

            # re: 自己造的一個線程類 2009-02-18 18:22 true
            陳:
            Run是純虛函數,必須重載,然后才能實例化。  回復  更多評論
              

            # re: 自己造的一個線程類 2009-03-10 15:13 陳頭
            請問如何顯示的析構 new 出來的線程類呢?
              回復  更多評論
              

            # re: 自己造的一個線程類 2009-03-10 15:28 true
            舉個例子:
            class CThreadTest : public CThread
            {
            protected:
            void Run(void* arg)
            {
            printf("arg = %s\n",(char*)arg);
            sleep(10);
            printf("after sleep 10s");
            }

            };
            步驟:
            1.char* pArg = "hello";CThreadTest *pTest = new CThreadTest
            2.pTest->Start(pArg);
            3.pTest->Wait();
            4.delete pTest;
            你可以在CThreadTest 里面實現,delete的時候,自動終止線程  回復  更多評論
              

            # re: 自己造的一個線程類 2009-03-14 23:21 zengfanmaio

            pthread_create第二個參數是空,默認有PTHREAD_CREATE_JOINABLE屬性。因此,析構的時候,也要調用一下pthread_join(對應Win32的CloseHandle)。如果設置了PTHREAD_CREATE_DETACHED就不需要。:)  回復  更多評論
              

            # re: 自己造的一個線程類 2009-03-16 08:34 true
            @zengfanmaio
            好久不見!!  回復  更多評論
              

            # re: 自己造的一個線程類 2009-03-24 19:20 老陳頭
            謝謝  回復  更多評論
              

            # re: 自己造的一個線程類[未登錄] 2009-09-11 20:16 欲三更
            謝謝分享,很通用的設計,VCL類庫里的TThread類基本就是這個樣子。

            說一點個人的想法:我自己寫的類也差不多是這樣,不過有一點差別:我個人認為“線程”和“線程要跑的任務”是兩個東西,前者是內核對象(抱歉,我總是改不了用win32本位思考)的抽象,跟具體功能沒關系,后者是功能的抽象,跟具體程序有關系。

            所以我傾向于把static THREAD_API Routine(void* arg)分離出來,成為一個ITask接口。

            這樣做還有一個好處,當Thread跑完了Task的代碼后可以阻塞在那里等待跑別的Task。

            另外我對protobuf也蠻感興趣的,但是我有點看不懂那個東西,功力太淺:)  回復  更多評論
              

            # re: 自己造的一個線程類 2009-09-11 20:34 true
            @ 欲三更
            線程的抽象問題,也算是見仁見智,你描述的方式類似boost的實現(好像是),而博文中的抽象是基于“主動對象”這個概念的,我個人覺得,“主動對象”更容易理解。
            libprotobuf是個好東東,多看幾遍就好了:),有啥問題可以一起交流。關于數據格式,還可以看一下json,感覺不錯。
              回復  更多評論
              

            综合网日日天干夜夜久久 | 亚洲七七久久精品中文国产| 久久精品国产男包| 亚洲精品无码久久不卡| 久久国产精品偷99| 成人精品一区二区久久久| 久久久久夜夜夜精品国产| 精品熟女少妇av免费久久| 久久久一本精品99久久精品88| 波多野结衣AV无码久久一区| 国产亚洲精久久久久久无码77777| 久久夜色精品国产www| 久久一区二区免费播放| 国产精品久久新婚兰兰| 久久伊人五月天论坛| 久久99亚洲综合精品首页| 国产精品午夜久久| 久久免费大片| 人妻精品久久久久中文字幕69| 激情伊人五月天久久综合| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 亚洲AV无码一区东京热久久| 亚洲乱码精品久久久久..| 久久天堂AV综合合色蜜桃网 | 精品久久久无码人妻中文字幕| 国产精品久久久久久五月尺| 看久久久久久a级毛片| 成人国内精品久久久久影院| 国产成人精品久久综合| 久久人人爽人人爽人人av东京热 | 精品久久久久久亚洲| 久久AAAA片一区二区| 色欲久久久天天天综合网精品| 91精品国产高清久久久久久国产嫩草| 久久久不卡国产精品一区二区| 一本久道久久综合狠狠爱| 国产精品免费久久| 久久棈精品久久久久久噜噜| 欧美亚洲国产精品久久久久| 久久线看观看精品香蕉国产| 亚洲人成精品久久久久|