简介:线程池是一种常见的并发编程模式,可以提高程序的性能和资源利用率。本篇博客介绍了如何使用C++来实现一个简单的线程池,以便更好地利用系统资源和管理并发任务。
学习惯例,先来了解一下什么是线程池?
线程池是一种并发编程的设计模式,它可以在程序运行时创建一组预先初始化的线程,并且通过将待执行的任务分配给这些线程来提高执行效率。线程池可以帮助我们更好地管理系统资源,并实现任务的并行处理。
为什么要使用线程池(线程池的优势)
使用线程池的好处包括:
- 避免了线程频繁创建和销毁的开销。
- 控制并发线程的数量,避免系统资源被过度消耗。
- 提高任务的执行效率,通过复用线程来减少线程创建和上下文切换的开销。
- 更容易管理和调试线程的执行。
上代码(线程池的实现过程)
下面是一个简单的线程池的实现过程的示例代码,我们使用C++11提供的线程库来实现:
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <functional>
std::mutex ex_mtx;
class ThreadPool {
public:
explicit ThreadPool(size_t threadNum): stop(false) {
for (size_t i = 0; i < threadNum; i++) {
threads.emplace_back([this]{
while(true) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]{ return stop || !tasks.empty(); });
if (stop && tasks.empty()) {
return;
}
task = std::move(tasks.front());
tasks.pop();
}
task();
}
});
}
}
~ThreadPool() {
{
std::unique_lock<std::mutex> lock(mtx);
stop = true;
}
cv.notify_all();
for(std::thread& thread : threads) {
thread.join();
}
}
template<class F, class... Args>
void enqueue(F&& f, Args&&... args) {
{
std::unique_lock<std::mutex> lock(mtx);
auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
tasks.emplace([task]{ task(); });
}
cv.notify_one();
}
private:
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
std::mutex mtx;
std::condition_variable cv;
bool stop;
};
void exampleTask(int num) {
std::lock_guard<std::mutex> lock(ex_mtx);
std::cout<< "Task " << num << "started." << std::endl;
std::cout << "当前线程的真实线程 ID:" << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout<< "Task " << num << "finished." << std::endl;
}
int main() {
ThreadPool pool(4); // 创建一个具有4个线程的线程池
// 创建五个任务并使用enqueue提交给线程池
for (int i = 0; i < 5; i++) {
pool.enqueue(exampleTask, i);
}
// 等待任务执行完成,主线程可以从这里继续工作
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout<< "exit process" << std::endl;
return 0;
}
在上面的示例中,我们首先定义了一个 ThreadPool
类,该类包含了线程池的各种成员变量和方法。在构造函数中,我们创建了指定数量的工作线程,并通过一个无限循环来获取任务并执行。任务队列使用了一个线程安全的队列和互斥锁来实现。
enqueue
方法用于将任务添加到任务队列中,并通过条件变量来通知等待中的工作线程有任务可执行。在析构函数中,我们首先停止线程池的运行,然后通知所有的工作线程退出,并等待它们的退出。
exampleTas
方法中使用互斥锁锁住共享代码区域,使各线程互斥访问;
在 main
函数中,我们创建了一个线程池,并添加了8个任务到线程池中。我们通过 std::this_thread::sleep_for
方法来模拟任务的执行时间,最后等待所有任务完成。
总结
本篇博客介绍了如何使用C++来实现一个简单的线程池。线程池可以帮助我们更好地管理系统资源和处理并发任务,提高程序的性能和效率。希望通过本篇文章的介绍,您能更好地理解并应用线程池的概念和实现方法。
这是一个简单的线程池的实现示例,使用的std::thread
来创建线程池,读者也可以使用boost库或者pthread来实现。希望这篇博客对您有所帮助!如果您有任何问题,请随时提问。