C++创建线程池

6 篇文章 0 订阅
1 篇文章 0 订阅

池:

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

一  定义自己的线程

#pragma once
#ifndef MYTHREAD
#define MYTHREAD
#include <iostream>
#include <windows.h>
//线程要做的事情
typedef unsigned int(*jobFunction)(int num,WPARAM wParam, LPARAM lParam);
//线程完成后回调
typedef void(*jobCallback)(unsigned int pResult);
class MyThread
{
public:
	MyThread();
	~MyThread();
	bool isWorking();//是否在工作
	void doJob(jobFunction jobPrac, int num,WPARAM wParam, LPARAM lParam, jobCallback cb);   //指派任务
private:
	bool bIsWorking;
	jobFunction m_jobFunc;
	jobCallback m_jobCallback;
	int num;
	WPARAM wParam;
	LPARAM lParam;
	HANDLE m_pHread;
	void jobDone();// 线程挂起
	static DWORD WINAPI threadProc(LPARAM lParam);   //真正线程
};
#endif // MYTHREAD
#include "Mythread.h"
MyThread::MyThread()
{
	 bIsWorking = false;
	 m_jobFunc = 0;
	 m_jobCallback = 0;
	 num = 0;
	 wParam = 0;
	 lParam = 0;
	//m_pHread = INVALID_HANDLE_VALUE;
	 //创建线程
	m_pHread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)threadProc,this,0,0); 
	printf("new thread %08x\n",m_pHread);
}
MyThread::~MyThread()
{
	//if (m_pHread != INVALID_HANDLE_VALUE)
	//{
	//	TerminateThread(m_pHread,0); //强制自杀
	//}
		if (m_pHread != INVALID_HANDLE_VALUE)
		{
			m_jobCallback = (jobCallback)INVALID_HANDLE_VALUE;
			m_jobFunc = (jobFunction)INVALID_HANDLE_VALUE;
			ResumeThread(m_pHread);
			WaitForSingleObject(m_pHread,INFINITE);
			CloseHandle(m_pHread);
		}
}
bool MyThread::isWorking()
{
	return this->bIsWorking;
}
void MyThread::jobDone()
{
	this->bIsWorking = false;
	SuspendThread(m_pHread);  //休眠
	//printf("thread %08x job done\n",m_pHread);
}
/*
执行一个具体的任务
*/
void MyThread::doJob(jobFunction jobPrac,int num, WPARAM wParam, LPARAM lParam, jobCallback cb)
{
	this->num = num;
	this->m_jobCallback = cb;
	this->m_jobFunc = jobPrac;
	this->wParam = wParam;
	this->lParam = lParam;
	ResumeThread(m_pHread);  //ResumeThread()使用该函数能够激活线程的运行,
							 //使CPU分配资源让线程恢复运行。
	printf("thread %08x start work..num %d wParam %d lParam  %d\n",m_pHread, num,wParam, lParam);
}
/*
真正的线程函数
*/
DWORD WINAPI MyThread::threadProc(LPARAM lParam)
{
	MyThread *pthis = (MyThread *)lParam;
	while (true)
	{  //因为线程在构造函数中申请的,但是申请的时候没有具体的任务
		if (pthis->m_jobCallback == INVALID_HANDLE_VALUE || pthis->m_jobFunc == INVALID_HANDLE_VALUE)
		{
			printf("thread %08x see byebye",pthis->m_pHread);
			break;
		}
		if (pthis->m_jobCallback == 0 || pthis->m_jobFunc == 0)
		{
			pthis->jobDone();
			//return;   不能直接return
			//continue;
		}
		pthis->bIsWorking = true;
		unsigned int result = pthis->m_jobFunc(pthis->num,pthis->wParam,pthis->lParam);
		printf("thread %08x job result %d\n",pthis->m_pHread,result);
		pthis->m_jobCallback(result);
		pthis->jobDone();
	}
	return 0;
}

二 创建线程池 

#pragma once
#include <vector>
#include "Mythread.h"
using namespace std;
#ifndef MYPOOL
#define MYPOOL

/*
池的概念:预先从操作系统申请大片资源,然后使用后不还给系统,保持复用
优点:避免频繁从应用层切换到内核<操作系统申请资源需要嵌入内核当中去>
*/

/*
线程池管理类,需要作为一个管理者,管理N个线程
*/
class MyPool
{
public:
	MyPool(int nSize);
	~MyPool();
	bool pushJob(jobFunction jobPrac, int num,WPARAM wParam, LPARAM lParam, jobCallback cb);
	int getPoolSize();
private:
	vector<MyThread *>m_threadVector;
};

#endif // !MYPOOL
#include "Mypool.h"

//在构造在初始化几个线程
MyPool::MyPool(int nSize)
{
	m_threadVector.clear();
	for (int i = 0; i < nSize; ++i)
	{
		MyThread *tmp = new MyThread();
		m_threadVector.push_back(tmp);
	}
}
MyPool::~MyPool()
{
	vector<MyThread *>::iterator iter = m_threadVector.begin();
	for (; iter != m_threadVector.end(); iter++)
	{
		MyThread *tmp = *iter;
		delete tmp;
	}
}

bool MyPool::pushJob(jobFunction jobPrac, int num,WPARAM wParam, LPARAM lParam, jobCallback cb)
{
	vector<MyThread *>::iterator iter = m_threadVector.begin();
	for (;iter != m_threadVector.end();iter++)
	{
		MyThread *tmp = *iter;
		if (!tmp->isWorking())
		{
			tmp->doJob(jobPrac, num,wParam, lParam, cb);
			return true;
		}
	}
	MyThread *tmp = new MyThread();
	m_threadVector.push_back(tmp);
	tmp->doJob(jobPrac,num, wParam, lParam, cb);
	return true;
}

int MyPool::getPoolSize()
{
	return m_threadVector.size();
}

 三 启动线程池

#include <mutex>
#include "Mypool.h"

//typedef unsigned int(*jobFunction)(WPARAM wParam, LPARAM lParam);
//typedef void(*jobCallback)(unsigned int pResult);
mutex m;
unsigned int job(WPARAM wParam, LPARAM lParam)
{
	m.lock();
	printf("job doing :%d + %d = ?\n", wParam, lParam);
	//Sleep(500);
	return lParam + wParam;
	m.unlock();
}
unsigned int job1(int num,WPARAM wParam, LPARAM lParam)
{
	printf("job doing :1+2+3+...+%d= ?\n", num);
	return num *(num -1)/2;
}
void cb(unsigned int pResult)
{
	printf("job result:%d\n",pResult);
}
int main()
{
	MyPool *pool = new MyPool(2);
	while (true)
	{
		char cmd = getchar();
		if (cmd == 'q' || cmd == 'Q')
		{
			break;
		}
		printf("thread pool size :%d\n",pool->getPoolSize());
		pool->pushJob(job1,100,0,0,cb);
	}
	printf("process exit\n");
	return 0;
}

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
创建线程池的步骤如下: 1. 初始化线程池的配置,包括保留线程的数量、线程池最大的线程数量等等。 2. 设置线程池的运行状态为运行中。 3. 记录初始线程的个数,并设置当前线程数量为初始线程数量。 4. 创建线程对象,并将线程函数绑定到线程池的私有成员变量上。 5. 启动所有线程,即创建线程、启动线程、执行线程函数。每个线程会查看任务队列是否有任务,若有则执行任务。同时记录初始空闲线程的数量。 6. 线程池创建完成。 以上是创建线程池的基本步骤,涉及到多线程编程的相关知识和技术,包括C++11的多线程库,如thread、mutex、atomic、condition_variable等,以及C++17和C++20标准中的一些内容,比如any类型和信号量semaphore。另外,熟悉多线程的基本知识、线程互斥、线程同步、原子操作、CAS等也是非常重要的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【C++实现】线程池的设计与实现](https://blog.csdn.net/weixin_52344401/article/details/127961779)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [C++11线程池实现](https://blog.csdn.net/xyygudu/article/details/128767928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值