zoukankan      html  css  js  c++  java
  • 基于Win32 SDK实现的一个简易线程池

    利用C++实现了一个简易的线程池模型(基于Win32 SDK),方便使用多线程处理任务。共包含Thread.h、Thread.cpp、ThreadPool.h、ThreadPool.cpp四个源文件。功能相对简单,尚待完善。

    Thread.h

     1 // Thread.h: interface for the CThread class.
     2 //
     3 //////////////////////////////////////////////////////////////////////
     4 
     5 #if !defined(AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_)
     6 #define AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_
     7 
     8 #if _MSC_VER > 1000
     9 #pragma once
    10 #endif // _MSC_VER > 1000
    11 
    12 class CThread  
    13 {
    14 public:
    15     CThread();
    16     virtual ~CThread();
    17 
    18 public:
    19     BOOL  IsBusy();
    20     void  Terminate();
    21     DWORD GetThreadId() const;
    22     void  Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);
    23 
    24 protected:
    25     void _SetBusy(BOOL bBusy);
    26 
    27 private:
    28     void __Proc();
    29     static DWORD WINAPI __ThreadProc(LPVOID lpParameter);
    30 
    31 protected:
    32     LPTHREAD_START_ROUTINE m_pThreadProc;
    33     LPVOID m_pParameter;
    34 
    35     BOOL m_bBusy;
    36     CRITICAL_SECTION m_csBusy;
    37 
    38     HANDLE m_hEventWait;
    39     HANDLE m_hEventExit;
    40 
    41     HANDLE m_hThread;
    42     DWORD  m_dwThreadId;
    43 };
    44 
    45 #endif // !defined(AFX_THREAD_H__9BC45342_F764_4104_B614_1CC8A1964171__INCLUDED_)

    Thread.cpp

     1 // Thread.cpp: implementation of the CThread class.
     2 //
     3 //////////////////////////////////////////////////////////////////////
     4 
     5 #include "StdAfx.h"
     6 #include "Thread.h"
     7 
     8 
     9 CThread::CThread()
    10 : m_pThreadProc(0)
    11 , m_pParameter(0)
    12 , m_bBusy(0)
    13 , m_hThread(0)
    14 {
    15     m_hEventWait = CreateEvent(0, TRUE, FALSE, NULL);
    16     m_hEventExit = CreateEvent(0, TRUE, FALSE, NULL);
    17     InitializeCriticalSection(&m_csBusy);
    18     m_hThread = CreateThread(0, 0, __ThreadProc, this, 0, &m_dwThreadId);
    19 }
    20 
    21 CThread::~CThread()
    22 {
    23     Terminate();
    24     WaitForSingleObject(m_hThread, INFINITE);
    25     CloseHandle(m_hThread);
    26     DeleteCriticalSection(&m_csBusy);
    27     CloseHandle(m_hEventWait);
    28     CloseHandle(m_hEventExit);
    29 }
    30 
    31 void CThread::Terminate()
    32 {
    33     SetEvent(m_hEventExit);
    34 }
    35 
    36 BOOL CThread::IsBusy()
    37 {
    38     EnterCriticalSection(&m_csBusy);
    39     BOOL bRet = m_bBusy;
    40     LeaveCriticalSection(&m_csBusy);
    41     return bRet;
    42 }
    43 
    44 void CThread::_SetBusy(BOOL bBusy)
    45 {
    46     EnterCriticalSection(&m_csBusy);
    47     m_bBusy = bBusy;
    48     LeaveCriticalSection(&m_csBusy);
    49 }
    50 
    51 DWORD CThread::GetThreadId() const
    52 {
    53     return m_dwThreadId;
    54 }
    55 
    56 void CThread::Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)
    57 {
    58     if (!IsBusy() && lpStartAddress)
    59     {
    60         _SetBusy(TRUE);
    61         m_pThreadProc = lpStartAddress;
    62         m_pParameter = lpParameter;
    63         SetEvent(m_hEventWait);
    64     }
    65 }
    66 
    67 DWORD WINAPI CThread::__ThreadProc(LPVOID lpParameter)
    68 {
    69     CThread* pThis = (CThread*)lpParameter;
    70     pThis->__Proc();
    71 
    72     return 0;
    73 }
    74 
    75 void CThread::__Proc()
    76 {
    77     for (;;)
    78     {
    79         if (!m_pThreadProc)
    80         {
    81             HANDLE hEvents[2] = {m_hEventExit, m_hEventWait};
    82             DWORD dwRet = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE);
    83             if (dwRet - WAIT_OBJECT_0 == 0) break;
    84         }
    85         m_pThreadProc(m_pParameter);
    86         m_pThreadProc = NULL;
    87         m_pParameter = NULL;
    88         ResetEvent(m_hEventWait);
    89         _SetBusy(FALSE);
    90     }
    91 }

    ThreadPool.h

     1 // ThreadPool.h: interface for the CThreadPool class.
     2 //
     3 //////////////////////////////////////////////////////////////////////
     4 
     5 #if !defined(AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_)
     6 #define AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_
     7 
     8 #if _MSC_VER > 1000
     9 #pragma once
    10 #endif // _MSC_VER > 1000
    11 
    12 #pragma warning(push)
    13 #pragma warning(disable: 4786)
    14 
    15 #include <queue>
    16 #include <vector>
    17 #include <utility>
    18 
    19 #pragma warning(pop)
    20 
    21 class CThread;
    22 class CThreadPool  
    23 {
    24 public:
    25     CThreadPool(size_t nMaxCount);
    26     virtual ~CThreadPool();
    27 
    28 public:
    29     BOOL IsBusy();
    30     BOOL Wait(DWORD dwMilliseconds);
    31     void Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter);
    32 
    33 private:
    34     void __Proc();
    35     static DWORD WINAPI __ThreadProc(LPVOID lpParameter);
    36 
    37 protected:
    38     HANDLE m_hThread;
    39     HANDLE m_hEventExit;
    40 
    41     CRITICAL_SECTION m_csFunc;
    42 
    43     std::vector<CThread*> m_vThreads;
    44     std::queue< std::pair<LPTHREAD_START_ROUTINE, LPVOID> > m_qFuncs;
    45 };
    46 
    47 #endif // !defined(AFX_THREADPOOL_H__E24F5439_D623_4511_A874_40CC9417DDEE__INCLUDED_)

    ThreadPool.cpp

      1 // ThreadPool.cpp: implementation of the CThreadPool class.
      2 //
      3 //////////////////////////////////////////////////////////////////////
      4 
      5 #include "StdAfx.h"
      6 #include "Thread.h"
      7 #include <algorithm>
      8 #include "ThreadPool.h"
      9 
     10 
     11 CThreadPool::CThreadPool(size_t nMaxCount)
     12 {
     13     for (size_t i(0); i < nMaxCount; ++i)
     14     {
     15         m_vThreads.push_back(new CThread);
     16     }
     17     InitializeCriticalSection(&m_csFunc);
     18     m_hEventExit = CreateEvent(NULL, TRUE, FALSE, NULL);
     19     m_hThread = CreateThread(0, 0, __ThreadProc, this, 0, 0);
     20 }
     21 
     22 CThreadPool::~CThreadPool()
     23 {
     24     SetEvent(m_hEventExit);
     25     WaitForSingleObject(m_hThread, INFINITE);
     26     CloseHandle(m_hThread);
     27     for (std::vector<CThread*>::iterator i(m_vThreads.begin())
     28         ; i != m_vThreads.end(); ++i)
     29     {
     30         delete *i;
     31     }
     32     m_vThreads.clear();
     33     DeleteCriticalSection(&m_csFunc);
     34 }
     35 
     36 DWORD WINAPI CThreadPool::__ThreadProc(LPVOID lpParameter)
     37 {
     38     CThreadPool* pThis = (CThreadPool*)lpParameter;
     39     pThis->__Proc();
     40 
     41     return 0;
     42 }
     43 
     44 void CThreadPool::__Proc()
     45 {
     46     for (;WaitForSingleObject(m_hEventExit, 100) != WAIT_OBJECT_0;)
     47     {
     48         EnterCriticalSection(&m_csFunc);
     49         if (!m_qFuncs.empty())
     50         {
     51             for (std::vector<CThread*>::iterator i(m_vThreads.begin())
     52                 ; i != m_vThreads.end(); ++i)
     53             {
     54                 if (!(*i)->IsBusy() && !m_qFuncs.empty())
     55                 {
     56                     std::pair<LPTHREAD_START_ROUTINE, LPVOID>& pFunc = m_qFuncs.front();
     57                     (*i)->Run(pFunc.first, pFunc.second);
     58                     m_qFuncs.pop();
     59                 }
     60             }
     61         }
     62         LeaveCriticalSection(&m_csFunc);
     63     }
     64 }
     65 
     66 void CThreadPool::Run(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)
     67 {
     68     EnterCriticalSection(&m_csFunc);
     69     std::pair<LPTHREAD_START_ROUTINE, LPVOID> pFunc(std::make_pair(lpStartAddress, lpParameter));
     70     m_qFuncs.push(pFunc);
     71     LeaveCriticalSection(&m_csFunc);
     72 }
     73 
     74 BOOL CThreadPool::IsBusy()
     75 {
     76     BOOL bRet(FALSE);
     77     EnterCriticalSection(&m_csFunc);
     78     if (m_qFuncs.empty())
     79     {
     80         for (std::vector<CThread*>::iterator i(m_vThreads.begin())
     81             ; i != m_vThreads.end(); ++i)
     82         {
     83             if ((*i)->IsBusy())
     84             {
     85                 bRet = TRUE;
     86                 break;
     87             }
     88         }
     89     }
     90     else bRet = TRUE;
     91     LeaveCriticalSection(&m_csFunc);
     92     return bRet;
     93 }
     94 
     95 BOOL CThreadPool::Wait(DWORD dwMilliseconds)
     96 {
     97     DWORD dwTick = GetTickCount();
     98     for (;IsBusy();)
     99     {
    100         Sleep(1);
    101         if (GetTickCount() - dwTick > dwMilliseconds)
    102         {
    103             break;
    104         }
    105     }
    106     return !IsBusy();
    107 }

    使用示例:

     1 // Test.cpp : Defines the entry point for the console application.
     2 //
     3 
     4 #include "StdAfx.h"
     5 #include "ThreadPool.h"
     6 
     7 CRITICAL_SECTION cs;
     8 
     9 using namespace std;
    10 
    11 DWORD WINAPI ThreadProc(LPVOID lpParameter)
    12 {
    13     EnterCriticalSection(&cs);
    14     cout << LPCSTR(lpParameter) << endl;
    15     LeaveCriticalSection(&cs);
    16     return 0;
    17 }
    18 
    19 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    20 {
    21     InitializeCriticalSection(&cs);
    22         
    23     CThreadPool *pThrealPool = new CThreadPool(2);
    24     pThrealPool->Run(ThreadProc, "001");
    25     pThrealPool->Run(ThreadProc, "002");
    26     pThrealPool->Run(ThreadProc, "003");
    27     pThrealPool->Run(ThreadProc, "004");
    28     pThrealPool->Run(ThreadProc, "005");
    29     pThrealPool->Run(ThreadProc, "006");
    30     pThrealPool->Run(ThreadProc, "007");
    31         
    32     pThrealPool->Wait(INFINIE);
    33     delete pThrealPool;
    34         
    35     DeleteCriticalSection(&cs);
    36 
    37     return nRetCode;
    38 }

     运行结果:

    源代码下载:http://t.cn/RvnJe9S

  • 相关阅读:
    在多租户(容器)数据库中如何创建PDB:方法6 DBCA本地克隆PDB
    在多租户(容器)数据库中如何创建PDB:方法5 DBCA远程克隆PDB
    1级搭建类104-Oracle 12cR2 单实例 FS(阿里云)公开
    在多租户(容器)数据库中如何创建PDB:方法4 克隆远程Non-CDB
    在多租户(容器)数据库中如何创建PDB:方法3 克隆远程PDB
    番外:克隆本地PDB中其他参数和子句的说明
    在多租户(容器)数据库中如何创建PDB:方法2 克隆本地PDB
    Oracle Solaris 10 重启后提示 Bad PBR sig
    在多租户(容器)数据库中如何创建PDB:方法1 从种子创建PDB
    0级搭建类009-Fedora 30 安装(F30) 公开
  • 原文地址:https://www.cnblogs.com/cpper-kaixuan/p/3801782.html
Copyright © 2011-2022 走看看