C++多線程編程(線程類)

簡述

通過線程類來管理線程,實現業務邏輯與線程管理分離

源代碼

接口類 SFRunnable.h

class SFRunnable
{
    public:
        virtual ~SFRunnable() {};
        virtual void Run() = 0;
};

線程類 SFThread.h

#ifndef __SFTHREAD_H__
#define __SFTHREAD_H__

#include <string>
#include <windows.h>
#include <process.h>

#include "SFRunnable.h"


class SFThread : public SFRunnable
{
private:
    explicit SFThread(const SFThread & rhs);//explicit

public:
    SFThread();
    SFThread(SFRunnable * pRunnable);
    SFThread(const char * ThreadName, SFRunnable * pRunnable = NULL);
    SFThread(std::string ThreadName, SFRunnable * pRunnable = NULL);
    ~SFThread(void);

    /**
      開始運行線程
      @arg bSuspend 開始運行時是否掛起
    **/
    bool Start(bool bSuspend = false);

    /**
      運行的線程函數,可以使用派生類重寫此函數
    **/
    virtual void Run();

    /**
      當前執行此函數線程等待線程結束
      @arg timeout 等待超時時間,如果爲負數,等待無限時長
    **/
    void Join(int timeout = -1);
    /**
      恢復掛起的線程
    **/
    void Resume();
    /**
      掛起線程
    **/
    void Suspend();
    /**
      終止線程的執行
    **/
    bool Terminate(unsigned long ExitCode);

    unsigned int GetThreadID();
    std::string GetThreadName();
    void SetThreadName(std::string ThreadName);
    void SetThreadName(const char * ThreadName);

private:
    static unsigned int WINAPI StaticThreadFunc(void * arg);//線程處理函數

private:
    HANDLE m_handle;//線程句柄
    SFRunnable * const m_pRunnable;//執行邏輯的指針
    unsigned int m_ThreadID;//線程ID
    std::string m_ThreadName;//線程name
    volatile bool m_bRun;//線程是否運行
};

#endif


/*
volatile:A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
*/

SFThread.cpp

#include "SFThread.h"

SFThread::SFThread(void) : m_pRunnable(NULL),m_bRun(false)//進入構造函數之前 先初始化 成員變量 有一些成員變量 必須先初始化 比如常量什麼的
{
}

SFThread::~SFThread(void)
{
}

SFThread::SFThread(SFRunnable * pRunnable) : m_ThreadName(""),m_pRunnable(pRunnable),m_bRun(false)
{
}

SFThread::SFThread(const char * ThreadName, SFRunnable * pRunnable) : m_ThreadName(ThreadName),m_pRunnable(pRunnable),m_bRun(false)
{
}

SFThread::SFThread(std::string ThreadName, SFRunnable * pRunnable) : m_ThreadName(ThreadName),m_pRunnable(pRunnable),m_bRun(false)
{
}

bool SFThread::Start(bool bSuspend)
{
    if(m_bRun)
    {
        return true;
    }
    if(bSuspend)
    {
        m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, CREATE_SUSPENDED, &m_ThreadID);
    }
    else
    {
        m_handle = (HANDLE)_beginthreadex(NULL, 0, StaticThreadFunc, this, 0, &m_ThreadID);
    }
    m_bRun = (NULL != m_handle);
    return m_bRun;
}

void SFThread::Run()
{
    if(!m_bRun)//如果沒運行
    {
        return;
    }
    if(NULL != m_pRunnable)//如果句柄不爲空
    {
        m_pRunnable->Run();
    }
    m_bRun = false;
}

void SFThread::Join(int timeout)
{
    if(NULL == m_handle || !m_bRun)
    {
        return;
    }
    if(timeout <= 0)
    {
        timeout = INFINITE;
    }
    ::WaitForSingleObject(m_handle, timeout);
}

void SFThread::Resume()
{
    if(NULL == m_handle || !m_bRun)
    {
        return;
    }
    ::ResumeThread(m_handle);
}

void SFThread::Suspend()
{
    if(NULL == m_handle || !m_bRun)
    {
        return;
    }
    ::SuspendThread(m_handle);
}

bool SFThread::Terminate(unsigned long ExitCode)
{
    if(NULL == m_handle || !m_bRun)
    {
        return true;
    }
    if(::TerminateThread(m_handle, ExitCode))
    {
        ::CloseHandle(m_handle);
        m_bRun  =   false;//設置線程的運行狀態爲假
        return true;
    }
    return false;
}

unsigned int SFThread::GetThreadID()
{
    return m_ThreadID;
}

std::string SFThread::GetThreadName()
{
    return m_ThreadName;
}

void SFThread::SetThreadName(std::string ThreadName)
{
    m_ThreadName = ThreadName;
}

void SFThread::SetThreadName(const char * ThreadName)
{
    if(NULL == ThreadName)
    {
        m_ThreadName = "";
    }
    else
    {
        m_ThreadName = ThreadName;
    }
}

unsigned int SFThread::StaticThreadFunc(void * arg)
{
    SFThread * pThread = (SFThread *)arg;
    pThread->Run();
    return 0;
}

業務類 SFTimer.h

#ifndef SFTimer_H
#define SFTimer_H

#include<windows.h>
#include"SFThread.h"
#define WM_UPDATETIME WM_USER+101 //用戶消息,每秒發送一次。

class SFTimer:public SFRunnable
{
    private:
        HWND hwnd;
        int Day;
        int Hour;
        int Minute;
        int Second;

        void init();//初始化天、小時、分鐘、秒全部爲零
        void CountDown();//倒計時
        void Time();//正計時
    public:
        SFTimer();
        SFTimer(HWND hwnd);

        int     getDay();
        void    setDay(int day);
        int     getHour();
        void    setHour(int hour);
        int     getMinute();
        void    setMinute(int minute);
        int     getSecond();
        void    setSecond(int second);

        void Run();
        void SendUploadTimeMessage();
};

#endif

SFTmier.cpp

#include "SFTimer.h"

SFTimer::SFTimer()
{
    this->init();
}

SFTimer::SFTimer(HWND hwnd)
{
    this->init();
    this->hwnd  =   hwnd;
}


int SFTimer::getDay()
{
    return this->Day;
}
void SFTimer::setDay(int day)
{
    this->Day   =   day;
}

int SFTimer::getHour()
{
    return this->Hour;
}
void SFTimer::setHour(int hour)
{
    this->Hour  =   hour;
}

int SFTimer::getMinute()
{
    return this->Minute;
}
void SFTimer::setMinute(int minute)
{
    this->Minute    =   minute;
}

int SFTimer::getSecond()
{
    return this->Second;
}
void SFTimer::setSecond(int second)
{
    this->Second    =   second;
}

void SFTimer::SendUploadTimeMessage()
{
    PostMessage(this->hwnd,WM_UPDATETIME,this->Minute,this->Second);
}
void SFTimer::init()
{
    this->Day       =   0;
    this->Hour      =   0;
    this->Minute    =   0;
    this->Second    =   0;
}
void SFTimer::CountDown()
{
    for(;this->Day>=0;this->Day--)//天循環
    {
        for(;this->Hour>=0;this->Hour--)//小時循環
        {


            for(; this->Minute >=0; this->Minute--)//分鐘循環
            {

                for(; this->Second >=0; this->Second--)//秒循環
                {
                    Sleep(1000);//Sleep看清楚間
                    this->SendUploadTimeMessage();//發送消息
                }
                this->Second = 59;
            }

        }
    }   
}

void SFTimer::Time()
{
    this->init();//初始化各個參數
    while(this->Minute<5)//5分鐘計時
    {
        this->Second+=1;
        if(this->Second >   60)
        {
            this->Second    =   0;
            this->Minute    +=  1;

            if(this->Minute >   60)
            {
                this->Minute    =   0;
                this->Hour  +=  1;
                if(this->Hour   >   60)
                {
                    this->Hour  =   0;
                    this->Day   +=1;
                }
            }
        }
        this->SendUploadTimeMessage();
        Sleep(1000);
    }
}

void SFTimer::Run()
{   
    this->CountDown();
    this->Time();
}

測試代碼 testMain.cpp

#include <iostream>

using namespace std;

#include "SFTimer.h"
#include "SFThread.h"

int main(int argc, char *argv[])  
{  
    SFTimer*    timer   =   new SFTimer();//具體業務類

    timer->setDay(0);//設置天
    timer->setHour(0);//設置小時
    timer->setMinute(2);//設置分鐘
    timer->setSecond(0);//設置秒

    SFThread* thread    =   new SFThread(timer);//線程類
    thread->Start();//啓動線程

    while(1)
    {
        cout<<"計時開始:"<<timer->getMinute()<<"分"<<timer->getSecond()<<"秒"<<endl; 
        Sleep(1000);//Sleep看清楚間
        system("cls");
    }

    getchar();

    return 0;  
}

實現效果

如下圖所示:實現2分鐘倒計時,以及5分鐘正計時。
這裏寫圖片描述

發佈了17 篇原創文章 · 獲贊 19 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章