win32线程池代码(WinApi/C++)

win32线程池代码(WinApi/C++)

健壮, 高效,易用,易于扩, 可用于任何C++编译器
//说明, 这段代码我用了很久, 我删除了自动调整规模的代码(因为他还不成熟)
/******************************************************************
*  Thread Pool For Win32
*  VC++ 6, BC++ 5.5(Free), GCC(Free)
*  Update : 2004.6.9 llBird  wushaojian@21cn.com

Use:
1):
void threadfunc(void *p)
{
 //...
}
 ThreadPool tp;
 for(i=0; i<100; i++)
  tp.Call(threadfunc);

 ThreadPool tp(20);//20为初始线程池规模
 tp.Call(threadfunc, lpPara);
 tp.AdjustSize(50);//增加50
 tp.AdjustSize(-30);//减少30


2):
class MyThreadJob : public ThreadJob //线程对象从ThreadJob扩展
{
public:
 virtual void DoJob(void *p)//自定义的虚函数
 {
  //....
 }
};
 MyThreadJob mt[10];
 ThreadPool tp;
 for(i=0; i<100 i++)
  tp.Call(mt + i);//tp.Call(mt + i, para);

*******************************************************************/
#ifndef _ThreadPool_H_
#define _ThreadPool_H_

#pragma warning(disable: 4530)
#pragma warning(disable: 4786)

#include <cassert>
#include <vector>
#include <queue>
#include <windows.h>


class ThreadJob  //工作基类
{
public:
 //供线程池调用的虚函数
 virtual void DoJob(void *pPara) = 0;
};

class ThreadPool
{

public:
 //dwNum 线程池规模
 ThreadPool(DWORD dwNum = 4) : _lThreadNum(0), _lRunningNum(0)
 {
  InitializeCriticalSection(&_csThreadVector);
  InitializeCriticalSection(&_csWorkQueue);

  _EventComplete = CreateEvent(0, false, false, NULL);
  _EventEnd = CreateEvent(0, true, false, NULL);
  _SemaphoreCall = CreateSemaphore(0, 0,  0x7FFFFFFF, NULL);
  _SemaphoreDel =  CreateSemaphore(0, 0,  0x7FFFFFFF, NULL);

  assert(_SemaphoreCall != INVALID_HANDLE_VALUE);
  assert(_EventComplete != INVALID_HANDLE_VALUE);
  assert(_EventEnd != INVALID_HANDLE_VALUE);
  assert(_SemaphoreDel != INVALID_HANDLE_VALUE);

  AdjustSize(dwNum <= 0 ? 4 : dwNum);
 }

 ~ThreadPool()
 {
  DeleteCriticalSection(&_csWorkQueue);

  CloseHandle(_EventEnd);
  CloseHandle(_EventComplete);
  CloseHandle(_SemaphoreCall);
  CloseHandle(_SemaphoreDel);
 
  vector<ThreadItem*>::iterator iter;
  for(iter = _ThreadVector.begin(); iter != _ThreadVector.end(); iter++)
  {
   if(*iter)
    delete *iter;
  }

  DeleteCriticalSection(&_csThreadVector);
 }
 //调整线程池规模
 int AdjustSize(int iNum)
 {
  if(iNum > 0)
  {
   ThreadItem *pNew;
   EnterCriticalSection(&_csThreadVector);
   for(int _i=0; _i<iNum; _i++)
   {
    _ThreadVector.push_back(pNew = new ThreadItem(this));
    assert(pNew);
    pNew->_Handle = CreateThread(NULL, 0, DefaultJobProc, pNew, 0, NULL);
    assert(pNew->_Handle);
   }
   LeaveCriticalSection(&_csThreadVector);
  }
  else
  {
   iNum *= -1;
   ReleaseSemaphore(_SemaphoreDel,  iNum > _lThreadNum ? _lThreadNum : iNum, NULL);
  }
  return (int)_lThreadNum;
 }
 //调用线程池
 void Call(void (*pFunc)(void  *), void *pPara = NULL)
 {
  assert(pFunc);

  EnterCriticalSection(&_csWorkQueue);
  _JobQueue.push(new JobItem(pFunc, pPara));
  LeaveCriticalSection(&_csWorkQueue);

  ReleaseSemaphore(_SemaphoreCall, 1, NULL);
 }
 //调用线程池
 inline void Call(ThreadJob * p, void *pPara = NULL)
 {
  Call(CallProc, new CallProcPara(p, pPara));
 }
 //结束线程池, 并同步等待
 bool EndAndWait(DWORD dwWaitTime = INFINITE)
 {
  SetEvent(_EventEnd);
  return WaitForSingleObject(_EventComplete, dwWaitTime) == WAIT_OBJECT_0;
 }
 //结束线程池
 inline void End()
 {
  SetEvent(_EventEnd);
 }
 inline DWORD Size()
 {
  return (DWORD)_lThreadNum;
 }
 inline DWORD GetRunningSize()
 {
  return (DWORD)_lRunningNum;
 }
 bool IsRunning()
 {
  return _lRunningNum > 0;
 }

protected:

 //工作线程
 static DWORD WINAPI DefaultJobProc(LPVOID lpParameter = NULL)
 {
  ThreadItem *pThread = static_cast<ThreadItem*>(lpParameter);
  assert(pThread);

  ThreadPool *pThreadPoolObj = pThread->_pThis;
  assert(pThreadPoolObj);

  InterlockedIncrement(&pThreadPoolObj->_lThreadNum);

  HANDLE hWaitHandle[3];
  hWaitHandle[0] = pThreadPoolObj->_SemaphoreCall;
  hWaitHandle[1] = pThreadPoolObj->_SemaphoreDel;
  hWaitHandle[2] = pThreadPoolObj->_EventEnd;

  JobItem *pJob;
  bool fHasJob;
 
  for(;;)
  {
   DWORD wr = WaitForMultipleObjects(3, hWaitHandle, false, INFINITE);

   //响应删除线程信号
   if(wr == WAIT_OBJECT_0 + 1) 
    break;
  
   //从队列里取得用户作业
   EnterCriticalSection(&pThreadPoolObj->_csWorkQueue);
   if(fHasJob = !pThreadPoolObj->_JobQueue.empty())
   {
    pJob = pThreadPoolObj->_JobQueue.front();
    pThreadPoolObj->_JobQueue.pop();
    assert(pJob);
   }
   LeaveCriticalSection(&pThreadPoolObj->_csWorkQueue);

   //受到结束线程信号 确定是否结束线程(结束线程信号 && 是否还有工作)
   if(wr == WAIT_OBJECT_0 + 2 && !fHasJob) 
    break;

   if(fHasJob && pJob)
   {
    InterlockedIncrement(&pThreadPoolObj->_lRunningNum);
    pThread->_dwLastBeginTime = GetTickCount();
    pThread->_dwCount++;
    pThread->_fIsRunning = true;
    pJob->_pFunc(pJob->_pPara); //运行用户作业
    delete pJob;
    pThread->_fIsRunning = false;
    InterlockedDecrement(&pThreadPoolObj->_lRunningNum);
   }
  }

  //删除自身结构
  EnterCriticalSection(&pThreadPoolObj->_csThreadVector);
  pThreadPoolObj->_ThreadVector.erase(find(pThreadPoolObj->_ThreadVector.begin(), pThreadPoolObj->_ThreadVector.end(), pThread));
  LeaveCriticalSection(&pThreadPoolObj->_csThreadVector);

  delete pThread;

  InterlockedDecrement(&pThreadPoolObj->_lThreadNum);

  if(!pThreadPoolObj->_lThreadNum)  //所有线程结束
   SetEvent(pThreadPoolObj->_EventComplete);

  return 0;
 }
 //调用用户对象虚函数
 static void CallProc(void *pPara)
 {
  CallProcPara *cp = static_cast<CallProcPara *>(pPara);
  assert(cp);
  if(cp)
  {
   cp->_pObj->DoJob(cp->_pPara);
   delete cp;
  }
 }
 //用户对象结构
 struct CallProcPara 
 {
  ThreadJob* _pObj;//用户对象
  void *_pPara;//用户参数
  CallProcPara(ThreadJob* p, void *pPara) : _pObj(p), _pPara(pPara) { };
 };
 //用户函数结构
 struct JobItem
 {
  void (*_pFunc)(void  *);//函数
  void *_pPara; //参数
  JobItem(void (*pFunc)(void  *) = NULL, void *pPara = NULL) : _pFunc(pFunc), _pPara(pPara) { };
 };
 //线程池中的线程结构
 struct ThreadItem
 {
  HANDLE _Handle; //线程句柄
  ThreadPool *_pThis;  //线程池的指针
  DWORD _dwLastBeginTime; //最后一次运行开始时间
  DWORD _dwCount; //运行次数
  bool _fIsRunning;
  ThreadItem(ThreadPool *pthis) : _pThis(pthis), _Handle(NULL), _dwLastBeginTime(0), _dwCount(0), _fIsRunning(false) { };
  ~ThreadItem()
  {
   if(_Handle)
   {
    CloseHandle(_Handle);
    _Handle = NULL;
   }
  }
 };
 
 std::queue<JobItem *> _JobQueue;  //工作队列
 std::vector<ThreadItem *>  _ThreadVector; //线程数据

 CRITICAL_SECTION _csThreadVector, _csWorkQueue; //工作队列临界, 线程数据临界

 HANDLE _EventEnd, _EventComplete, _SemaphoreCall, _SemaphoreDel;//结束通知, 完成事件, 工作信号, 删除线程信号
 long _lThreadNum, _lRunningNum; //线程数, 运行的线程数

};

#endif //_ThreadPool_H_

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
使用C++代码封装的win32操作类, 与MFC相似,对于学习SDK与C++是巨好的参考 Tutorials Menu of tutorials Tutorial 1: The Simplest Window Tutorial 2: Using Classes and Inheritance Tutorial 3: Using Messages to Create a Scribble Window Tutorial 4: Repainting the Window Tutorial 5: Wrapping a Frame around our Scribble Window Tutorial 6: Customising Window Creation Tutorial 7: Customising the Toolbar Tutorial 8: Loading and Saving Files Tutorial 9: Printing Tutorial 10: Finishing Touches Tutorial 1: The Simplest Window The following code uses Win32++ to create a window. This is all the code you need (in combination with Win32++) to create and display a simple window. Note that in order to add the Win32++ code to our program, we use an #include statement as shown below. #include "../Win32++/Wincore.h" INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { //Start Win32++ CWinApp MyApp; //Create a CWnd object CWnd MyWindow; //Create (and display) the window MyWindow.Create(); //Run the application return MyApp.Run(); } This program has four key steps: Start Win32++. We do this here by creating a CWinApp object called MyApp. Create a CWnd object called MyWindow. Create a default window by calling the Create function. Start the message loop, by calling the Run function. If you compile and run this program, you'll find that the application doesn't end when the window is closed. This is behaviour is normal. An illustration of how to use messages to control the windows behaviour (including closing the application) will be left until tutorial 3.
以下是一个简单的VC++ 6.0 Win32五子棋代码示例: ```c++ #include <windows.h> #define CELL_SIZE 30 // 棋盘格子大小 #define BOARD_SIZE 15 // 棋盘大小 #define WINDOW_WIDTH (CELL_SIZE * BOARD_SIZE + 20) #define WINDOW_HEIGHT (CELL_SIZE * BOARD_SIZE + 20) LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc = {0}; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszClassName = TEXT("FiveChessClass"); RegisterClass(&wc); HWND hwnd = CreateWindow(TEXT("FiveChessClass"), TEXT("Five Chess"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg = {0}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HBRUSH hWhiteBrush = CreateSolidBrush(RGB(255, 255, 255)); // 白色画刷 static HBRUSH hBlackBrush = CreateSolidBrush(RGB(0, 0, 0)); // 黑色画刷 static int board[BOARD_SIZE][BOARD_SIZE] = {0}; // 棋盘 static int curPlayer = 1; // 当前玩家,1表示黑方,2表示白方 static int winner = 0; // 获胜者,0表示无人获胜,1表示黑方获胜,2表示白方获胜 static BOOL gameOver = FALSE; // 游戏是否结束 switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); // 绘制棋盘 for (int i = 0; i < BOARD_SIZE; ++i) { for (int j = 0; j < BOARD_SIZE; ++j) { RECT rect = {i * CELL_SIZE + 10, j * CELL_SIZE + 10, (i + 1) * CELL_SIZE + 10, (j + 1) * CELL_SIZE + 10}; if (board[i][j] == 1) { FillRect(hdc, &rect, hBlackBrush); } else if (board[i][j] == 2) { FillRect(hdc, &rect, hWhiteBrush); } else { Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); } } } // 绘制获胜者 if (gameOver) { TCHAR szWinner[32] = {0}; if (winner == 1) { wsprintf(szWinner, TEXT("Black player wins!")); } else if (winner == 2) { wsprintf(szWinner, TEXT("White player wins!")); } else { wsprintf(szWinner, TEXT("Game over!")); } TextOut(hdc, 10, CELL_SIZE * BOARD_SIZE + 20, szWinner, lstrlen(szWinner)); } EndPaint(hwnd, &ps); break; } case WM_LBUTTONDOWN: { if (gameOver) { break; } int x = LOWORD(lParam); int y = HIWORD(lParam); if (x < 10 || x > WINDOW_WIDTH - 10 || y < 10 || y > WINDOW_HEIGHT - 10) { break; } int i = (x - 10) / CELL_SIZE; int j = (y - 10) / CELL_SIZE; if (board[i][j] != 0) { break; } board[i][j] = curPlayer; // 判断获胜者 int dx[4] = {1, 0, 1, -1}; int dy[4] = {0, 1, 1, 1}; for (int k = 0; k < 4; ++k) { int count = 1; for (int p = 1; p <= 4; ++p) { int newi = i + p * dx[k]; int newj = j + p * dy[k]; if (newi < 0 || newi >= BOARD_SIZE || newj < 0 || newj >= BOARD_SIZE || board[newi][newj] != curPlayer) { break; } ++count; } for (int p = 1; p <= 4; ++p) { int newi = i - p * dx[k]; int newj = j - p * dy[k]; if (newi < 0 || newi >= BOARD_SIZE || newj < 0 || newj >= BOARD_SIZE || board[newi][newj] != curPlayer) { break; } ++count; } if (count >= 5) { winner = curPlayer; gameOver = TRUE; break; } } // 切换玩家 curPlayer = 3 - curPlayer; // 重新绘制窗口 InvalidateRect(hwnd, NULL, TRUE); break; } default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } ``` 该示例代码使用了Win32 API和GDI进行图形界面的绘制和处理,实现了一个能够双人对战的五子棋游戏。在游戏中会根据玩家的落子情况判断是否获胜,并在游戏结束后显示获胜者。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值