返回
C++学习记录:从一个小线程池源码看C++11新特性的优雅使用
后端
2023-11-01 12:11:41
最近抽空学习一些感兴趣的源码,这次学习一个小而美的C++11线程池源码。核心代码很简单,就是下面这不到一百行。但是其中使用了很多新C++11的新东西,写的非常优雅,有很多可以学习的地方。
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <condition_variable>
class ThreadPool {
public:
ThreadPool(int num_threads) : num_threads_(num_threads) {
for (int i = 0; i < num_threads_; ++i) {
threads_.emplace_back([this] {
while (true) {
std::unique_lock<std::mutex> lock(mutex_);
if (tasks_.empty()) {
cv_.wait(lock);
}
auto task = std::move(tasks_.front());
tasks_.pop();
lock.unlock();
task();
}
});
}
}
~ThreadPool() {
{
std::lock_guard<std::mutex> lock(mutex_);
stop_ = true;
cv_.notify_all();
}
for (auto& thread : threads_) {
thread.join();
}
}
void addTask(std::function<void()> task) {
std::lock_guard<std::mutex> lock(mutex_);
tasks_.push(std::move(task));
cv_.notify_one();
}
private:
std::vector<std::thread> threads_;
std::mutex mutex_;
std::condition_variable cv_;
std::queue<std::function<void()>> tasks_;
bool stop_ = false;
int num_threads_;
};
int main() {
ThreadPool pool(4);
for (int i = 0; i < 10; ++i) {
pool.addTask([i] {
std::cout << "Task " << i << " is running." << std::endl;
});
}
return 0;
}
这个线程池源码的核心思想很简单,就是使用一个队列来存储任务,然后使用多个线程来处理队列中的任务。当队列为空时,线程会等待,当有任务加入队列时,线程会唤醒并执行任务。
这个源码中使用了许多新C++11的新特性,包括:
- 智能指针:使用
std::unique_lock
来管理互斥量,这种智能指针会在析构时自动解锁互斥量,非常方便。 - 标准库:使用了
std::thread
、std::mutex
、std::condition_variable
等标准库中的并发原语。 - 并发:使用了多个线程来并行执行任务,提高了程序的性能。
- 互斥量:使用了
std::mutex
来保护共享数据,防止多个线程同时访问共享数据。
这个线程池源码写的非常优雅,代码简洁易懂,而且性能也非常不错。如果你想学习C++11的新特性,或者想学习如何编写一个线程池,这个源码是一个非常好的参考。
除了上述优点之外,这个线程池源码还有以下一些特点:
- 可以通过构造函数指定线程池的大小,这样可以根据实际需要来调整线程池的性能。
- 线程池会自动回收空闲的线程,这样可以节省系统资源。
- 线程池可以方便地添加任务,只需要调用
addTask()
方法即可。
总之,这个线程池源码是一个非常优秀的作品,值得我们学习和借鉴。