线程池的实现v1.0

61 阅读1分钟

说明

在高并发的任务中线程的创建和销毁都是有开销的,因此预先把线程创建好,到时候从线程池中去取就可以了。

线程池头文件

#pragma once
#include <thread>
#include <mutex>
#include <vector>
#include <list>

class XTask
{
public:
	virtual int Run() = 0;  // 任务的入口函数
};

class XThreadPool
{
public:
	// 初始化线程池
	// num 为线程的数量
	void Init(int num);

	// 启动所有线程,调用前必须先调用Init
	void Start();

	// 插入任务
	void AddTask(XTask * task);

	// 获取任务
	XTask* GetTask();
private:
	// 线程池线程的入口函数
	void Run();
	int thread_num_ = 0;  // 线程数量
	std::mutex mux_;
	std::vector<std::thread*> threads_;
	std::list<XTask*> tasks_;
	std::condition_variable cv_;
};


线程池实现文件

#include "x_thread_pool.h"
#include <iostream>

using namespace std;

void XThreadPool::Init(int num)
{
	unique_lock<mutex> lock(mux_);
	this->thread_num_ = num;

	cout << "Thread pool init " << num << "\n";
}

// 启动所有线程,必须先调用Init

void XThreadPool::Start()
{
	unique_lock<mutex> lock(mux_);

	if (thread_num_ <= 0)
	{
		cerr << "Please Init XThreadPool" << "\n";
	}

	if (!threads_.empty())
	{
		cerr << "Thread pool has start!" << "\n";
	}

	// 启动线程
	for (int i = 0; i < thread_num_; i++)
	{
		auto th = new thread(&XThreadPool::Run, this);
		threads_.push_back(th);
	}


}

void XThreadPool::Run()
{
	cout << "begin XThreadPool Run" << this_thread::get_id() << '\n';

	while(true)
	{
		auto task = GetTask();
		if (!task) continue;
		try
		{
			task->Run();
		} catch (...)
		{
			
		}
	}

	cout << "exit XThreadPool Run" << this_thread::get_id() << '\n';

}

void XThreadPool::AddTask(XTask* task)
{
	unique_lock<mutex> lock(mux_);
	tasks_.push_back(task);

	lock.unlock();
	cv_.notify_one();

}

XTask* XThreadPool::GetTask()
{
	unique_lock<mutex> lock(mux_);

	if (tasks_.empty())
	{
		cv_.wait(lock);

	}

	if (tasks_.empty())
	{
		return nullptr;
	}

	auto task = tasks_.front();

	tasks_.pop_front();
	return task;

}


启动线程池入口文件


#include <iostream>
#include "x_thread_pool.h"

class MyTask:public XTask
{
public:
    int Run() override
    {
	    std::cout << "MyTask" << name << '\n';
        return 0;
    }

    std::string name = "";
};

int main()
{

    XThreadPool pool;
    pool.Init(16);
    pool.Start();

    MyTask task1;
    task1.name = "test name 001";

    pool.AddTask(&task1);

    getchar();

    return 0;

}