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

            網(wǎng)絡(luò)服務(wù)器軟件開發(fā)/中間件開發(fā),關(guān)注ACE/ICE/boost

            C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
              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;//是否已經(jīng)“取消”該線程
                bool      m_bStarted;//線程已經(jīng)啟動(dòng)

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

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

                
            void Terminate(void);//強(qiáng)制退出

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


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

                
            virtual void Run(void* arg) = 0;//1.子類重載此函數(shù),在run里面完成所有功能.2.子類要檢查GetStopFlag(),以配合對(duì)該線程的“停止”;或者采用強(qiáng)制終止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 閱讀(2783) 評(píng)論(12)  編輯 收藏 引用 所屬分類: linux

            Feedback

            # re: 自己造的一個(gè)線程類 2009-01-19 14:13 eXile
            Win32最好不要使用CreateThread, 使用 _beginthreadex  回復(fù)  更多評(píng)論
              

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

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

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

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

            # re: 自己造的一個(gè)線程類 2009-03-10 15:13 陳頭
            請(qǐng)問如何顯示的析構(gòu) new 出來的線程類呢?
              回復(fù)  更多評(píng)論
              

            # re: 自己造的一個(gè)線程類 2009-03-10 15:28 true
            舉個(gè)例子:
            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 里面實(shí)現(xiàn),delete的時(shí)候,自動(dòng)終止線程  回復(fù)  更多評(píng)論
              

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

            pthread_create第二個(gè)參數(shù)是空,默認(rèn)有PTHREAD_CREATE_JOINABLE屬性。因此,析構(gòu)的時(shí)候,也要調(diào)用一下pthread_join(對(duì)應(yīng)Win32的CloseHandle)。如果設(shè)置了PTHREAD_CREATE_DETACHED就不需要。:)  回復(fù)  更多評(píng)論
              

            # re: 自己造的一個(gè)線程類 2009-03-16 08:34 true
            @zengfanmaio
            好久不見!!  回復(fù)  更多評(píng)論
              

            # re: 自己造的一個(gè)線程類 2009-03-24 19:20 老陳頭
            謝謝  回復(fù)  更多評(píng)論
              

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

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

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

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

            另外我對(duì)protobuf也蠻感興趣的,但是我有點(diǎn)看不懂那個(gè)東西,功力太淺:)  回復(fù)  更多評(píng)論
              

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

            国产精品成人精品久久久| 久久人人爽人人精品视频| 亚洲色婷婷综合久久| 色综合久久久久综合体桃花网| 久久综合精品国产二区无码| 韩国免费A级毛片久久| 国内精品久久久久影院网站 | 久久99精品久久只有精品| 久久国产精品成人免费| 久久亚洲精品国产精品婷婷 | 久久er热视频在这里精品| 久久久久久无码Av成人影院| 欧洲精品久久久av无码电影| 国产99久久久国产精品~~牛| 欧美亚洲国产精品久久| 狠狠色综合久久久久尤物| 日韩人妻无码精品久久免费一| 国产午夜电影久久| 久久人人爽人人爽人人片av高请| 91精品久久久久久无码| 久久A级毛片免费观看| 亚洲国产天堂久久久久久| 99久久人人爽亚洲精品美女 | 人人狠狠综合久久88成人| 久久se这里只有精品| 77777亚洲午夜久久多喷| 怡红院日本一道日本久久 | 麻豆国内精品久久久久久| a高清免费毛片久久| 午夜天堂精品久久久久| 亚洲天堂久久久| 久久精品国产亚洲Aⅴ蜜臀色欲| 996久久国产精品线观看| 久久久久久人妻无码| 久久午夜无码鲁丝片| 亚洲中文精品久久久久久不卡| 国产欧美久久久精品影院| 午夜精品久久影院蜜桃| 亚洲国产精品无码久久久久久曰| 久久午夜福利电影| 久久久久无码中|