目录
简单的线程池
在 C++11 中,你可以使用 std::thread 和 std::mutex 等标准库来实现一个简单的线程池。以下是一个简单的示例代码:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <queue>
class ThreadPool {
private:
// 线程池大小
size_t poolSize;
// 任务队列
std::queue<std::function<void()>> tasks;
// 锁
std::mutex mtx;
// 条件变量
std::condition_variable cv;
// 线程数
size_t numThreads;
public:
ThreadPool(size_t poolSize) : poolSize(poolSize), numThreads(0) {}
void addTask(const std::function<void()> &task) {
std::unique_lock<std::mutex> lock(mtx);
tasks.push(task);
// 通知一个等待的线程
cv.notify_one();
}
~ThreadPool() {
// 等待所有任务完成
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{return tasks.empty();});
}
private:
void worker() {
for (;;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(mtx);
// 等待任务
cv.wait(lock, []{return !tasks.empty();});
task = tasks.front();
tasks.pop();
}
// 执行任务
task();
}
}
};
int main() {
ThreadPool pool(4);
for (int i = 0; i < 10; ++i) {
pool.addTask([]() { std::cout << "Task " << i << " is running on thread " << std::this_thread::get_id() << std::endl; });
}
pool.addTask([]() { std::cout << "All tasks are done" << std::endl; });
std::vector<std::thread> threads;
for (size_t i = 0; i < pool.poolSize; ++i) {
threads.push_back(std::thread(&ThreadPool::worker, &pool));
}
for (auto &thread : threads) {
thread.join();
}
return 0;
}
在上面的示例中, ThreadPool 类有以下几个关键部分:
- poolSize 表示线程池的大小。
- tasks 是一个任务队列,使用 std::queue 实现。
- mtx 是一个互斥锁,用于保护任务队列的访问。
- cv 是一个条件变量,用于通知等待的线程有任务可用。
- numThreads 表示当前运行的线程数。
在 addTask 方法中,使用 std::unique_lock 来获取互斥锁,并将任务添加到任务队列中。然后,使用 cv.notify_one 通知一个等待的线程。
在 worker 方法中,使用循环不断等待任务。在循环中,使用 std::unique_lock 来获取互斥锁,并使用 cv.wait 等待条件变量的信号。当有任务可用时,从队列中取出任务并执行。
在 main 函数中,创建一个线程池,并向其添加多个任务。最后,启动所有的线程,并等待所有任务完成。
请注意,这只是一个简单的线程池实现示例,可能不适用于所有情况。在实际应用中,你可能需要根据具体需求进行调整和优化。