C++多執行緒程式設計(執行緒類)
阿新 • • 發佈:2019-02-04
簡述
通過執行緒類來管理執行緒,實現業務邏輯與執行緒管理分離
原始碼
介面類 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分鐘正計時。