cpp实现线程池-半同步半异步

Lock.h

#pragma once

#include <mutex>
#include <condition_variable>


typedef std::recursive_mutex RecursiveMutex;
typedef std::lock_guard<RecursiveMutex> RecursiveLock;
typedef std::mutex Mutex;
typedef std::unique_lock<Mutex> AutoLock;
typedef std::condition_variable Condition;

ThreadPool.h

#pragma once

#include "Lock.h"
#include <functional>
#include <vector>
#include <deque>
#include <thread>


class ThreadPool
{
	typedef std::vector<std::thread*> ThreadPoolType;
	typedef std::function<void()> Task;
	typedef std::deque<Task> TaskQueueType;
public:
	// static ThreadPool& Instance()
	// {
	// 	static ThreadPool pool;
	// 	return pool;
	// }

	void SetQueueMaxSize(size_t nMaxSize)
	{
		m_nMaxQueueSize = nMaxSize;
	}
	void Start(int32_t nNumThreads);
	void Run(const Task& f);
	void Run(Task&& f);
	void Stop();
	size_t GetTaskQueueSize();
	void SetThreadInitCb(const Task& cb)
	{
		threadInitCb = cb;
	}
private:
	void ThreadFunc();
	Task TaskTake();
	bool IsFull()
	{
		return m_nMaxQueueSize>0 && m_dTaskQueue.size() >= m_nMaxQueueSize;
	}
private:
	int32_t m_nThreadNum{0};
	size_t m_nMaxQueueSize{0};

	ThreadPoolType m_vThreads;
	TaskQueueType m_dTaskQueue;
	Mutex m_Mutex;
	Condition m_NotEmptyCond;
	Condition m_NotFullCond;

	Task threadInitCb;
	bool m_bRunning{false};
};

ThreadPool.cpp

#include "ThreadPool.h"

void ThreadPool::Start(int32_t nNumThreads)
{
	if(nNumThreads == 0 && threadInitCb)
	{
		threadInitCb();
		return;
	}

	for(int i=0;i<nNumThreads;++i)
	{
		auto thrd = new std::thread(std::bind(&ThreadPool::ThreadFunc, this));
		m_vThreads.push_back(thrd);
	}
	m_bRunning = true;
}

void ThreadPool::Run(const Task& f)
{
	if(m_vThreads.empty())
	{
		return f();
	}
	AutoLock Lock(m_Mutex);
	while(IsFull())
	{
		m_NotFullCond.wait(Lock);
	}
	m_dTaskQueue.push_back(f);
	m_NotEmptyCond.notify_all();

}

void ThreadPool::Run(Task&& f)
{
	if(m_vThreads.empty())
	{
		return f();
	}
	AutoLock Lock(m_Mutex);
	while(IsFull())
	{
		m_NotFullCond.wait(Lock);
	}
	m_dTaskQueue.push_back(std::move(f));
	m_NotEmptyCond.notify_all();
}
#include <iostream>
void ThreadPool::Stop()
{
	AutoLock Lock(m_Mutex);
	m_bRunning = false;
	m_NotEmptyCond.notify_all();
	for(auto it = m_vThreads.begin();it != m_vThreads.end();)
	{
		it = m_vThreads.erase(it);
	}
	std::cout <<"stop thread pool" << std::endl;
}

size_t ThreadPool::GetTaskQueueSize()
{
	AutoLock Lock(m_Mutex);
	return m_dTaskQueue.size();
}

void ThreadPool::ThreadFunc()
{
	if(threadInitCb)
	{
		threadInitCb();
	}
	while(m_bRunning)
	{
		Task task = TaskTake();
		if(task)
		{
			task();
		}
	}
}

ThreadPool::Task ThreadPool::TaskTake()
{
	AutoLock Lock(m_Mutex);
	while(m_dTaskQueue.empty() && m_bRunning)
	{
		m_NotEmptyCond.wait(Lock);
	}
	Task task;
	if(!m_dTaskQueue.empty())
	{
		task = m_dTaskQueue.front();
		m_dTaskQueue.pop_front();
		m_NotFullCond.notify_all();
	}
	return task;
}

Test.cpp

#include "ThreadPool.h"
#include <iostream>
using namespace std;

void TestPoolPrintWithParam(const std::string &str)
{
    cout << "this is thread pool running" << endl;
    if (str.size() > 0)
    {
        cout << str << endl;
    }
}

void TestPoolPrint()
{
    cout << "this is thread pool running" << endl;
}

int main(int argc, char const *argv[])
{
    ThreadPool threadPool;
    threadPool.SetQueueMaxSize(5);
    threadPool.Start(3);
    threadPool.Run(TestPoolPrint);
    threadPool.Run(TestPoolPrint);
    for (int i = 0; i < 100; ++i)
    {
        char buf[32];
        snprintf(buf, sizeof buf, "task %d", i);
        threadPool.Run(std::bind(TestPoolPrintWithParam, std::string(buf)));
    }

    threadPool.Stop();
    return 0;
}

 编译: g++ ThreadPool.cpp ThreadPool.h Lock.h test.cpp -lpthread 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值