C++ 线程池
2017-12-02 18:15
204 查看
线程池
1. 创建任务类,处理执行的任务
2. 创建线程池类,创建多个线程,每个线程函数从任务列表获取需要执行的任务
3. 目前该程序还有Bug,需要继续优化
“F_Test_ThreadPool.h”文件
“F_ThreadPool.h”文件
“F_ThreadPool.cpp”文件
1. 创建任务类,处理执行的任务
2. 创建线程池类,创建多个线程,每个线程函数从任务列表获取需要执行的任务
3. 目前该程序还有Bug,需要继续优化
“F_Test_ThreadPool.h”文件
#ifndef F_Test_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_ #define F_Test_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_ #include <stdio.h> #include "F_ThreadPool.h" class CCopyFileTask: public CTask { public: CCopyFileTask(); public: bool CopyFileTask(); virtual void RunTask(); }; CCopyFileTask::CCopyFileTask() { } bool CCopyFileTask::CopyFileTask() { ::CopyFile(m_strTask_1, m_strTask_2,false); TRACE("成功拷贝文件:%s\n", m_strTask_1); Sleep(20); return true; } void CCopyFileTask::RunTask() { this->CopyFileTask(); return ; } //测试 void F_Test_ThreadPool() { TRACE("\n******************线程池测试******************\n"); #if 0 //此时用一个循环完成,调用同一函数拷贝150个文件,需要19s for(int i=1; i<=150; i++) { CString strSrcPath; CString strDesPath; strSrcPath.Format("D:\\IMAGE11\\82kv_6ma\\%d_82_6.RAW", i); strDesPath.Format("D:\\IMAGE11\\TEST\\%d_82_6.RAW", i); CCopyFileTask CopyFileIntence; CopyFileIntence.SetTaskData(strSrcPath, strDesPath); CopyFileIntence.RunTask(); Sleep(80); } #else int nThreadNum = 5; CThreadPool ThreadPool(nThreadNum); Sleep(1000); //此时用线程池(5个线程)完成,调用同一函数拷贝150个文件,需要10s for(int i=1; i<=150; i++) { CString strSrcPath; CString strDesPath; strSrcPath.Format("D:\\IMAGE11\\82kv_6ma\\%d_82_6.RAW", i); strDesPath.Format("D:\\IMAGE11\\TEST\\%d_82_6.RAW", i); CCopyFileTask CopyFileIntenceThreadPool; CopyFileIntenceThreadPool.SetTaskData(strSrcPath, strDesPath); ThreadPool.AddTaskToVector(&CopyFileIntenceThreadPool); Sleep(80); } #endif } #endif//F_Test_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_
“F_ThreadPool.h”文件
#ifndef F_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_ #define F_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_ /* 线程池技术 1. */ #include <stdio.h> #include <vector> #include <afxmt.h> using namespace std; /* 任务类 1. 抽象需要执行的任务 2. 用于具体任务的父类 */ class CTask { public: CTask(); CTask(CString strTaskName); virtual ~CTask(); public: //! 执行任务 virtual void RunTask() = 0; //! 设置需要执行的任务数据 void SetTaskData(void *pTaskData); //! 设置需要执行的任务数据 void SetTaskData(CString strTask_1, CString strTask_2); public: //! 任务名称 CString m_strTaskName; //! 需要执行的任务数据 void *m_pTaskData; CString m_strTask_1; CString m_strTask_2; }; /* 线程池类 1. 创建一定数量的线程 2. 线程函数,从任务列表中获取当前未开始处理的任务 */ class CThreadPool { public: CThreadPool(int nThreadNum); public: //! 添加任务到任务列表 void AddTaskToVector(CTask *pTask); //! 结束所有任务 void StopAllTask(); //! 获取当前任务列表中,未开始执行的任务数 int GetCurTasksNum(); private: //! 创建线程 void CreateThreads(); //! 线程执行函数,循环从任务列表获取第一个未执行的任务 static DWORD WINAPI ThreadFunc(LPVOID pTaskData); public: //! 保存任务的vector static vector<CTask *> m_vTasks; //! 当前任务列表中,未开始执行的任务数 int m_nCurTasksNum; //! 当前正在执行任务的线程ID LPDWORD m_pnThreadID; //! 线程数量 int m_nThreadNum; //! 退出线程标记 static bool m_bThreadExit; //! 线程锁 static CMutex m_MutexThread; //! 线程等待标志 static HANDLE m_hThreadWait; }; #endif//F_THREAD_POOL_2017_11_25_10_JHASKDFJHASF_H_
“F_ThreadPool.cpp”文件
#include "stdafx.h" #include "F_ThreadPool.h" vector<CTask *> CThreadPool::m_vTasks; CMutex CThreadPool::m_MutexThread = NULL; bool CThreadPool::m_bThreadExit = false; HANDLE CThreadPool::m_hThreadWait = CreateEvent(NULL, FALSE, FALSE, NULL); CTask::CTask() {} CTask::CTask(CString strTaskName) :m_strTaskName(strTaskName) {} CTask::~CTask() {} //设置需要执行的任务数据 void CTask::SetTaskData(void *pTaskData) { m_pTaskData = pTaskData; } //设置需要执行的任务数据 void CTask::SetTaskData(CString strTask_1, CString strTask_2) { m_strTask_1 = strTask_1; m_strTask_2 = strTask_2; } CThreadPool::CThreadPool(int nThreadNum) { m_nThreadNum = nThreadNum; //创建线程 CreateThreads(); } //创建线程 void CThreadPool::CreateThreads() { m_pnThreadID = new DWORD[m_nThreadNum]; int nCurThreadID(0); for(int i=0; i<m_nThreadNum; i++) { ::CreateThread(NULL, 0, ThreadFunc, (LPVOID)this, 0, &m_pnThreadID[i]); TRACE("\n创建线程:%d, 线程ID: %d", i+1, m_pnThreadID[i]); } for (int i=0; i<m_nThreadNum; i++) { TRACE("\n已经成功创建的线程ID: %d", m_pnThreadID[i]); } TRACE("\n线程池中线程数量: %d", m_nThreadNum); } //线程执行函数,循环从任务列表获取第一个未执行的任务 DWORD WINAPI CThreadPool::ThreadFunc(LPVOID pTaskData) { int nCurThreadID = GetCurrentThreadId(); TRACE("\n当前进入线程ID: %d", nCurThreadID); while(1) { m_MutexThread.Lock(); //如果此时没有任务,则线程等待 if(!m_bThreadExit && (m_vTasks.size() == 0)) { WaitForSingleObject(m_hThreadWait, INFINITE); //DWORD dwRet = WaitForMultipleObjects(2, &m_hThreadWait, FALSE, INFINITE); //if(dwRet == WAIT_OBJECT_0) //{ // break; //} } //退出线程 if(m_bThreadExit) { m_MutexThread.Unlock(); break; } //获取当前任务列表中的第一个任务 vector<CTask *>::iterator itFirstTask = m_vTasks.begin(); //将当前任务从任务列表擦掉 CTask *pTast = *itFirstTask; if(itFirstTask != m_vTasks.end()) { pTast = *itFirstTask; m_vTasks.erase(itFirstTask); } m_MutexThread.Unlock(); //处理任务 pTast->RunTask(); TRACE("\n线程ID: %d, 正在处理任务......", nCurThreadID); } TRACE("\n结束线程ID: %d", nCurThreadID); return 0; } //将任务添加进任务列表 void CThreadPool::AddTaskToVector(CTask *pTask) { //m_MutexThread.Lock(); m_vTasks.push_back(pTask); SetEvent(m_hThreadWait); //m_MutexThread.Unlock(); } //! 结束所有任务 void CThreadPool::StopAllTask() { m_bThreadExit = true; }
相关文章推荐