C++11 ThreadPool--半同步半异步线程池

SyncQueue.h:

半同步半异步队列

#pragma once
#include <list>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <iostream>

using namespace  std;
template<typename T>
class SyncQueue
{
public:
	SyncQueue(int maxSize) :m_maxSize(maxSize), m_needStop(false)
	{

	}
	void Put(const T&x)
	{
		Add(x);
	}
	void Put(T&& x)
	{
		Add(forward<T>(x));
	}

	void Take(list<T>& list)
	{
		/*
			1.先创建一个unique_lock获取mutex
			2.通过条件变量m_notEmpty来等待判断式(一个是停止的标志,另一个是不为空的条件)
			当不满足任何一个条件时,条件变量会释放mutex并将线程置于waiting状态,等待其它线程调用
			notify_one/notify_all将其唤醒;
			当满足任一条件时,则继续往下执行后面的逻辑,即将队列中的任务取出,并唤醒一个正处于等待状态的添加
			任务的线程去添加任务。
			3.当处于waiting状态的线程被notify_one或notify_all唤醒时,条件变量会先重新获取mutex,然后再检查条件是否
			满足,如果满足,则往下执行,如果不满足,则释放mutex继续等待
		*/
		unique_lock<mutex> locker(m_mutex);
		m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });

		if (m_needStop)
			return;
		list = move(m_queue);
		m_notFull.notify_one();
	}

	void Take(T& t)
	{
		unique_lock<mutex> locker(m_mutex);
		m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
		if (m_needStop)
			return;
		t = m_queue.front();
		m_queue.pop_front();
		m_notFull.notify_one();
	}

	void Stop()
	{
		{
			lock_guard<mutex> locker(m_mutex);
			m_needStop = true;
		}
		m_notFull.notify_all();
		m_notEmpty.notify_all();
	}

	bool Empty()
	{
		lock_guard<mutex> locker(m_mutex);
		return m_queue.empty();
	}

	bool Full()
	{
		lock_guard<mutex> locker(m_mutex);
		return m_queue.size() == m_maxSize;
	}

	size_t Size()
	{
		lock_guard<mutex> locker(m_mutex);
		return m_queue.size();
	}

	int Count()
	{
		return m_queue.size();
	}
private:
	bool NotFull()const
	{
		bool full = m_queue.size() >= m_maxSize;
		if (full)
			cout << "缓冲区满了,需要等待..." << endl;
		return !full;
	}

	bool NotEmpty()const
	{
		bool empty = m_queue.empty();
		if (empty)
			cout << "缓冲区空了,需要等待...,异步层的线程ID:" << this_thread::get_id() << endl;
		return !empty;
	}

	template<typename F>
	void Add(F&& x)
	{
		unique_lock<mutex> locker(m_mutex);
		m_notFull.wait(locker, [this] {return m_needStop || NotFull(); });
		if (m_needStop)
			return;
		m_queue.push_back(forward<F>(x));
		m_notEmpty.notify_one();
	}
private:
	list<T> m_queue;				//缓冲区
	mutex m_mutex;					//互斥量和条件变量结合超来使用
	condition_variable m_notEmpty;	//不为空的条件变量
	condition_variable m_notFull;	//没有满的条件变量
	int m_maxSize;					//同步队列最大的size
	bool m_needStop;				// 停止的标志
};

ThreadPool.h:线程池

#pragma once
#include <list>
#include <thread>
#include <functional>
#include <memory>
#include <atomic>
#include "SyncQueue.h"

using namespace std;

const int MaxTaskCount = 100;
class ThreadPool
{
public:
	using Task = function<void()>;
	ThreadPool(int numThreads = thread::hardware_concurrency()) :m_queue(MaxTaskCount)
	{
		Start(numThreads);
	}
	~ThreadPool()
	{
		// 如果没有停止时则主动停止线程池
		Stop();
	}

	void Stop()
	{
		// 保证多线程情况下只调用一次StopThreadGroup
		call_once(m_flag, [this] {StopThreadGroup(); });
	}

	void AddTask(Task&& task)
	{
		m_queue.Put(forward<Task>(task));
	}

	void AddTask(const Task& task)
	{
		m_queue.Put(task);
	}
private:
	void Start(int numThreads)
	{
		m_running = true;
		// 创建线程组
		for (int i =0;i<numThreads;++i)
		{
			m_threadgroup.push_back(make_shared<thread>(&ThreadPool::RunInThread, this));
		}
	}

	void RunInThread()
	{
		while (m_running)
		{
			// 取任务分别执行
			list<Task> list;
			m_queue.Take(list);
			for (auto& task:list)
			{
				if (!m_running)
					return;
				task();
			}
		}
	}
	void StopThreadGroup()
	{
		m_queue.Stop();		//让同步队列中的线程停止 
		m_running = false;	//置为false,让内部线程跳出循环并退出
		for (auto thread:m_threadgroup)		//等待线程结束
		{
			if (thread)
			{
				thread->join();
			}			
		}
		m_threadgroup.clear();
	}

private:
	list<shared_ptr<thread>> m_threadgroup; //处理任务的线程组
	SyncQueue<Task> m_queue;				//同步队列
	atomic_bool m_running;					// 是否停止的标志
	once_flag m_flag;
};

测试代码:

// ThreadPool.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include "ThreadPool.h"
#include <thread>

using namespace std;
int main()
{
	ThreadPool pool{2};
	thread thd1([&pool] {
		for (int i = 0;i<10;i++)
		{
			auto thdId = this_thread::get_id();
			pool.AddTask([thdId]
			{
				cout << "同步线程1的线程ID: " << thdId << endl;
			});
		}
	});

	thread thd2([&pool] {
		for (int i = 0;i<10;i++)
		{
			auto thdId = this_thread::get_id();
			pool.AddTask([thdId] {
				cout << "同步线程2的线程ID:" << thdId << endl;
			});
		}
	});

	this_thread::sleep_for(chrono::seconds(2));
	getchar();
	pool.Stop();
	thd1.join();
	thd2.join();
}


测试结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用C++线程池进行异步调用的示例: ```cpp #include <iostream> #include <thread> #include <functional> #include <vector> #include <queue> #include <mutex> #include <condition_variable> class ThreadPool { public: ThreadPool(size_t numThreads) : stop(false) { for (size_t i = 0; i < numThreads; ++i) { threads.emplace_back([this] { while (true) { std::function<void()> task; { std::unique_lock<std::mutex> lock(queueMutex); condition.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop && tasks.empty()) { return; } task = std::move(tasks.front()); tasks.pop(); } task(); } }); } } template<class F, class... Args> void enqueue(F&& f, Args&&... args) { { std::unique_lock<std::mutex> lock(queueMutex); tasks.emplace([=] { std::invoke(f, args...); }); } condition.notify_one(); } ~ThreadPool() { { std::unique_lock<std::mutex> lock(queueMutex); stop = true; } condition.notify_all(); for (std::thread& thread : threads) { thread.join(); } } private: std::vector<std::thread> threads; std::queue<std::function<void()>> tasks; std::mutex queueMutex; std::condition_variable condition; bool stop; }; // 示例任务函数 void printHello(int id) { std::cout << "Hello from thread " << id << std::endl; } int main() { ThreadPool pool(4); // 创建一个拥有4个线程的线程池 // 向线程池中添加任务 for (int i = 0; i < 10; ++i) { pool.enqueue(printHello, i); } // 等待所有任务完成 // 这里不需要使用pthread_join函数,线程池会自动处理任务的执行和完成 // 当线程池析构时,会等待所有任务完成后再退出 // 所以在这里不需要显式地调用join函数 // 但是需要注意的是,如果在线程池析构前没有等待所有任务完成,可能会导致任务被中断 // 所以在实际使用中,需要根据具体情况来决定何时销毁线程池 return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值