多线程基础架构 C++实现

前序

之前在实习的时候,leader为了锻炼我的学习能力,让我用wins api函数写一个多线程实际的应用案例,后来用MFC简单的封装一下,一个小型的类似于外卖系统抢单,派单的小逻辑~~,今天在项目运用中又遇到了需要提高效率的地方,所以想记录一下

线程池的,多线程的好处,同步,异步,互斥锁等等的概念在这里就不多说了~~

我就开门见山啦,,环境:VS2008

附上代码

Event类

class Event
{
public:
    Event();
    ~Event();
    void Wait() const;
    void Notify() const;

private:
    HANDLE hEvent;
};  

Event类实现

Event::Event()
{
    hEvent = CreateEvent(NULL,false,false,NULL); 
}

Event::~ Event()
{
    if(hEvent)
    ::CloseHandle(hEvent);
}

void Event::Wait() const
{
    WaitForSingleObject(hEvent, INFINITE);   
}

void Event::Notify() const
{
    ::SetEvent(hEvent);
}   

锁Mutex

class Mutex
{
public:
    Mutex();
    ~Mutex();
    void lock() const;
    void unlock() const;

private:
    HANDLE m_hMutex;
};

Mutex实现

Mutex::Mutex()
{
    m_hMutex = ::CreateMutex(NULL, FALSE, NULL);
}

Mutex::~ Mutex()
{
    ::CloseHandle(m_hMutex);
}

void Mutex::lock() const
{
    WaitForSingleObject(m_hMutex, INFINITE);   
}

void Mutex::unlock() const
{
    ::ReleaseMutex(m_hMutex);
}   

Task类

class Task
{
public: 
    Task(int stime);
    ~Task();
    void DoTask();
    unsigned int GetTaskId();
    void SetId(unsigned int Id);
    void SetHandle(HWND MainHandl);
    unsigned int GetRestTime();
    unsigned int sp_time;
    unsigned int RestTime;
    unsigned int ID;
    HWND m_Handle;
    Mutex T_mutex;
};

Task类实现

Task::Task(int sptime)
{   
    sp_time = sptime; 
    RestTime = sp_time;
}

Task::~Task()
{

}

void Task::SetId(unsigned int Id)
{
    ID = Id;
}

void Task::DoTask()
{  
    for (int i = 0; i <= sp_time; ++i) {
        RestTime = sp_time-i;
        ::PostMessage(m_Handle,WM_MYMESSAGE,NULL,NULL);
        Sleep(1000);
    }
}

unsigned int Task::GetTaskId()
{
    return ID;
}

void Task::SetHandle(HWND MainHandl)
{
    m_Handle = MainHandl;
}

unsigned int Task::GetRestTime()
{
    return RestTime;
}

ThreadBase类

扫描二维码关注公众号,回复: 1471100 查看本文章
//Class BaseThread
class BaseThread
{
public:
    BaseThread();
    virtual ~BaseThread();
protected:
    virtual void Run();
    HANDLE hThread;
    DWORD dwThreadId;
};

ThreadBase类实现

DWORD WINAPI WorkThread(LPVOID lpParam);
DWORD WINAPI WorkThread1(LPVOID lpParam);

BaseThread::BaseThread()
{

}

BaseThread::~BaseThread()
{

}

void BaseThread::Run()
{

}

TaskThread类

//Class TaskThread
class ThreadPool;

class TaskThread: public BaseThread
{
public:
    TaskThread();
    TaskThread(int Num);
    ~TaskThread();
    unsigned int TaskThreadNum();
    void Run();
    void SendTask(Task *p_Task); 
    void Create();
    void CancleTask(HWND MainHandl);
    bool GetPwork();
    Task *GetTask();
    bool GetPcancle();

    DWORD GetThreadID(){return dwThreadId;}

    Mutex s_Mutex;
    Event s_Event;
    Event p_Event;
    static int flag;
    bool p_Work;
    Task *m_Task;
    bool p_Cancle;
};

class MainThread: public BaseThread
{
public:
    MainThread();
    ~MainThread();
private:
    void Run();
};

TaskThread类实现

TaskThread::TaskThread()
{
    hThread = CreateThread(NULL, 0, WorkThread, this, 0, &dwThreadId);
    if(hThread==NULL) {
        ExitProcess(dwThreadId);
    }
    m_Task = NULL;
    p_Cancle = false;
}

MainThread::MainThread()
{
    HWND MainHandle = AfxGetMainWnd()->m_hWnd;
    hThread = CreateThread(NULL, 0, WorkThread1, MainHandle, 0, &dwThreadId);
    if(hThread==NULL) {
        ExitProcess(dwThreadId);
    }
}

TaskThread::~TaskThread()
{
    CloseHandle(hThread);

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

void TaskThread::Run()
{
    while(true) {
        s_Event.Wait();
        s_Mutex.lock();

        if (NULL != m_Task) {
            m_Task->DoTask();
        }
        m_Task = NULL;
        s_Mutex.unlock();

        if (p_Cancle == false) {
            ThreadPool::Instance()->MoveToIdleList(this); 
        }
    }
}

void TaskThread::SendTask(Task *p_Task)
{
    s_Mutex.lock();
    m_Task = p_Task;
    s_Mutex.unlock();
    s_Event.Notify();

}

bool TaskThread::GetPwork()
{
    return p_Work;
}

Task *TaskThread::GetTask()
{
    return m_Task;
}

bool TaskThread::GetPcancle()
{
    return p_Cancle;
}

void TaskThread::CancleTask(HWND MainHandle)
{
    p_Cancle = !p_Cancle;
    if (p_Cancle == true &&this->p_Work == false) {
        ThreadPool::Instance()->MoveToBusyList(this);
    }

    else if (p_Cancle == false && this->p_Work == true) {
        ThreadPool::Instance()->MoveToIdleList(this);
    }
    ::PostMessage(MainHandle,WM_MYMESSAGE,NULL,NULL);
}

DWORD WINAPI WorkThread(LPVOID lpParam)
{
    TaskThread *pThread = (TaskThread*)lpParam;
    pThread->Run();
    return 0;
}

DWORD WINAPI WorkThread1(LPVOID lpParam)
{
    HWND MainHdle = (HWND) lpParam;
    ThreadPool::Instance()->Run(MainHdle);
    return 0;
}

线程池 Threadpool

//Class ThreadPool
class ThreadPool{
public:
    static ThreadPool* Instance();
    ThreadPool();
    ~ThreadPool();
    void SendTask(Task *p_Task);
    //void CancelTask(Task *p_Task);
    void  Run(HWND MainHandle);

    std::vector<TaskThread*> m_Thread;
    std::vector<TaskThread*> m_BusyThread;
    std::vector<TaskThread*> m_IdleThread;
    std::list<Task*>m_TaskList;
    Event m_TaskEvent;
    Event m_IdleEvent;

    Mutex m_BusyMutex;
    Mutex m_IdleMutex;
    Mutex m_TaskMutex;

    static ThreadPool *s_ThreadPool;

    unsigned int m_InitNum;

    bool InstanceFlsg;

    TaskThread* GetIdleThread(void);

    void  AppendToIdleList(TaskThread* ss_thread); 
    void  MoveToBusyList(TaskThread* idlethread);
    void  MoveToIdleList(TaskThread* busythread);

};

线程池的实现


ThreadPool *ThreadPool::s_ThreadPool = NULL;

ThreadPool::ThreadPool()
{
    InstanceFlsg = false;
    m_InitNum = 3;
    m_BusyThread.clear();
    m_IdleThread.clear();
    m_TaskList.clear();

    for(int i = 0; i< m_InitNum; i++) {
        TaskThread* thr = new TaskThread(); 
        AppendToIdleList(thr);
    } 

}

ThreadPool *ThreadPool::Instance()
{
    if (NULL == s_ThreadPool) {
        s_ThreadPool = new ThreadPool();
    }
    return s_ThreadPool;
}


ThreadPool::~ThreadPool()
{
    for (int i = 0; i < m_InitNum; ++i) {
        if (NULL != m_Thread[i]) {
            delete m_Thread[i];
            m_Thread[i] = NULL;
        }
    }
}

TaskThread* ThreadPool::GetIdleThread(void) 
{
    m_IdleMutex.lock(); 

    if (m_IdleThread.size() > 0) {
         TaskThread* thr = (TaskThread*)m_IdleThread.front(); 
         std::cout<<"The Idlethread id is "<<thr->GetThreadID()<<std::endl; 
         m_IdleMutex.unlock(); 
         return thr;
    } 
    m_IdleMutex.unlock(); 
    return NULL; 
} 

void ThreadPool::MoveToBusyList(TaskThread* idlethread) 
{ 
    m_BusyMutex.lock(); 
    m_BusyThread.push_back(idlethread); 
    idlethread->p_Work = true;
    m_BusyMutex.unlock(); 

    m_IdleMutex.lock(); 
    std::vector<TaskThread*>::iterator pos; 
    pos = find(m_IdleThread.begin(),m_IdleThread.end(),idlethread); 

    if(pos !=m_IdleThread.end()) {
        m_IdleThread.erase(pos); 
    }

    m_IdleMutex.unlock(); 
} 

void ThreadPool::MoveToIdleList(TaskThread* busythread) 
{ 
    m_IdleMutex.lock();
    m_IdleThread.push_back(busythread);
    busythread->p_Work = false;
    m_IdleMutex.unlock();

    m_BusyMutex.lock(); 
    std::vector<TaskThread*>::iterator pos; 
    pos = find(m_BusyThread.begin(),m_BusyThread.end(),busythread); 

    if(pos!=m_BusyThread.end()) {
         m_BusyThread.erase(pos);
    } 

    m_BusyMutex.unlock(); 
    m_IdleEvent.Notify(); 

} 

void ThreadPool::AppendToIdleList(TaskThread* s_thread) 
{ 
    m_IdleMutex.lock(); 
    m_IdleThread.push_back(s_thread);
    s_thread->p_Work = false;
    m_Thread.push_back(s_thread);
    m_IdleMutex.unlock(); 
} 

void ThreadPool::SendTask(Task* p_Task)
{
    m_TaskMutex.lock();
    m_TaskList.push_back(p_Task);
    ::PostMessage(AfxGetMainWnd()->m_hWnd,WM_MYMESSAGE,NULL,NULL);
    m_TaskMutex.unlock();
    m_TaskEvent.Notify();
}

void ThreadPool::Run(HWND MainHandle)
{
    InstanceFlsg = true;
    Task* s_Task = NULL;
    while (true) {

        if (m_IdleThread.size() == 0) {
            m_IdleEvent.Wait();
        }

        else {

            if (m_TaskList.size() == 0) {
                m_TaskEvent.Wait();
            }

            else {
                s_Task = *(m_TaskList.begin());
                m_TaskList.pop_front();
                //::Postmessage(AfxGetMainWnd()->m_hWnd , WM_MYMESSAGE , NULL ,NULL);
                m_TaskMutex.lock();
                ::PostMessage(MainHandle,WM_MYMESSAGE,NULL,NULL);
                m_TaskMutex.unlock();

                if (NULL != s_Task) {
                    //Sleep(1000);//等待撤销的Thread
                    TaskThread* idlethr = GetIdleThread();
                    if (NULL != idlethr) {
                        MoveToBusyList(idlethr);
                        idlethr->SendTask(s_Task);
                    }

                }
            }
        }

    }
}

面临毕业的你们想加深对多线程的理解,可以自己去实际根据自己的想法去实装task类,显而易见的是上诉程序已经可以实现同步,即task源源不断的创建,丢到ThreadPool,ThreadPool会指派空闲的线程去这些task,能实现边丢task,变解决task~,线程之间逻辑在这里就不多说了~

有兴趣的也可以大概的去给这些task赋予优先级,即当线程不够时,优先解决优先级高的task~

同时附上之前MFC的一段关键代码

LRESULT CThreadAppDlg::OnMyMessage(WPARAM wParam, LPARAM lParam) 
{
    CEdit* pBoxOne1;
    pBoxOne1 = (CEdit*) GetDlgItem(IDC_EDIT1);

    CEdit* pBoxOne7;
    pBoxOne7 = (CEdit*) GetDlgItem(IDC_EDIT7);

    CEdit* pBoxOne4;
    pBoxOne4 = (CEdit*) GetDlgItem(IDC_EDIT4);

    CEdit* pBoxOne5;
    pBoxOne5 = (CEdit*) GetDlgItem(IDC_EDIT5);

    CString str;
    int t =ThreadPool::Instance()->m_TaskList.size();
    CString str1;
    m_2 = "剩余Task数目:";
    str1.Format(_T("%d"),t);
    m_2 += str1;
    pBoxOne1->SetWindowText(m_2);

    if (ThreadPool::Instance()->m_Thread[0]->GetPwork() == true && NULL != ThreadPool::Instance()->m_Thread[0]->GetTask()) {
        m_7 = "执行Task: ";
        str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[0]->GetTask()->GetTaskId());
        m_7 += str;

        if (ThreadPool::Instance()->m_Thread[0]->GetTask()->GetRestTime() != 0){
            m_7+=",执行时间还剩: ";
            str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[0]->GetTask()->GetRestTime());
            m_7 += str;
            m_7 += "秒";
        }

        else if (ThreadPool::Instance()->m_Thread[0]->GetPcancle() ==false){
            m_7 += ",Task执行完毕.等待执行新Task...";
        }

        else {
            m_7 = "线程休息中...";
        }

        pBoxOne7->SetWindowText(m_7);
    }

    else if (ThreadPool::Instance()->m_Thread[0]->GetPcancle() ==true ||(ThreadPool::Instance()->m_Thread[0]->GetPwork() == false && ThreadPool::Instance()->m_Thread[0]->GetPcancle() ==false && ThreadPool::Instance()->m_TaskList.size() > 0)) {
        m_7 = "线程休息中...";
        pBoxOne7->SetWindowText(m_7);
    }

    else if (ThreadPool::Instance()->m_Thread[0]->GetPwork() == false && ThreadPool::Instance()->m_Thread[0]->GetPcancle() ==false) {
        m_7 = "等待执行Task...";
        pBoxOne7->SetWindowText(m_7);
    }
    if (ThreadPool::Instance()->m_Thread[1]->GetPwork() == true && NULL != ThreadPool::Instance()->m_Thread[1]->GetTask()) {
        m_4 = "执行Task: ";
        str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[1]->GetTask()->GetTaskId());
        m_4 += str;

        if (ThreadPool::Instance()->m_Thread[1]->GetTask()->GetRestTime() != 0) {
            m_4+=",执行时间还剩: ";
            str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[1]->GetTask()->GetRestTime());
            m_4 += str;
            m_4 += "秒";
        }

        else if (ThreadPool::Instance()->m_Thread[1]->GetPcancle() ==false){
            m_4 += ",Task执行完毕.等待执行新Task...";
        }

        else {
            m_4 = "线程休息中...";
        }

        pBoxOne4->SetWindowText(m_4);
    }

    else if (ThreadPool::Instance()->m_Thread[1]->GetPcancle() ==true ||(ThreadPool::Instance()->m_Thread[0]->GetPwork() == false && ThreadPool::Instance()->m_Thread[1]->GetPcancle() ==false && ThreadPool::Instance()->m_TaskList.size() > 0)) {
        m_4 = "线程休息中...";
        pBoxOne4->SetWindowText(m_4);

    }

    else if (ThreadPool::Instance()->m_Thread[1]->GetPwork() == false && ThreadPool::Instance()->m_Thread[1]->GetPcancle() ==false) {
        m_4 = "等待执行Task...";
        pBoxOne4->SetWindowText(m_4);
    }

    if (ThreadPool::Instance()->m_Thread[2]->GetPwork() == true && NULL != ThreadPool::Instance()->m_Thread[2]->GetTask()) {
        m_5 = "执行Task: ";
        str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[2]->GetTask()->GetTaskId());
        m_5 += str;
        if (ThreadPool::Instance()->m_Thread[2]->GetTask()->GetRestTime() != 0){
            m_5+=",执行时间还剩: ";
            str.Format(_T("%d"),ThreadPool::Instance()->m_Thread[2]->GetTask()->GetRestTime());
            m_5 += str;
            m_5 += "秒";
        }

        else if (ThreadPool::Instance()->m_Thread[2]->GetPcancle() ==false){
            m_5 += ",Task执行完毕.等待执行新Task...";
        }

        else {
            m_5 = "线程休息中...";
        }
        pBoxOne5->SetWindowText(m_5);
    }

    else if (ThreadPool::Instance()->m_Thread[2]->GetPcancle() ==true ||(ThreadPool::Instance()->m_Thread[0]->GetPwork() == false && ThreadPool::Instance()->m_Thread[2]->GetPcancle() ==false && ThreadPool::Instance()->m_TaskList.size() > 0)) {
        m_5 = "线程休息中...";
        pBoxOne5->SetWindowText(m_5);
    }

    else if (ThreadPool::Instance()->m_Thread[2]->GetPwork() == false && ThreadPool::Instance()->m_Thread[2]->GetPcancle() ==false) {
        m_5 = "等待执行Task...";
        pBoxOne5->SetWindowText(m_5);
    }

    UpdateData(FALSE);
    return 0;
}

看不大懂的同学欢迎留言交流~~

猜你喜欢

转载自blog.csdn.net/breakpoints_/article/details/80405436