我正在尝试在 C++ 中创建自定义线程池实现,但是在提交 n 个线程任务后出现死锁,谁能解释为什么?
thread.hpp:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <vector>
#include <atomic>
#include <queue>
class ThreadPool {
public:
ThreadPool(size_t _n_threads, size_t _max_tasks=100);
void push(std::function<void()> _f);
inline size_t size() const { return threads.size(); }
~ThreadPool();
private:
void thread_function();
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
std::condition_variable new_task;
std::condition_variable free_task;
std::atomic<bool> running;
std::mutex queue_mutex;
size_t queue_size;
};
线程.cpp
ThreadPool::ThreadPool(size_t _n_threads, size_t _max_tasks)
: running(true)
, queue_size(_max_tasks)
{
threads.reserve(_n_threads);
if (_n_threads > std::thread::hardware_concurrency())
_n_threads = std::thread::hardware_concurrency();
for (int i = 0; i < _n_threads; ++i)
threads.push_back(std::thread(thread_function, this));
}
ThreadPool::~ThreadPool() {
running = false;
new_task.notify_all();
for (std::thread& thread : threads)
if (thread.joinable())
thread.join();
}
void ThreadPool::thread_function() {
std::function<void()> task;
while (true) {
std::unique_lock lock(queue_mutex);
new_task.wait(lock);
if (!running) return;
if (tasks.empty())
continue;
task = tasks.front();
tasks.pop();
lock.unlock();
free_task.notify_one();
task();
}
}
void ThreadPool::push(std::function<void()> _f) {
std::unique_lock lock(queue_mutex);
free_task.wait(lock, [this] {
return tasks.size() < queue_size;
});
tasks.push(_f);
lock.unlock();
new_task.notify_one();
}
对队列的每次访问都应与互斥对象同步,但我可以看到
thread_function
和 push()
方法都可能进入死锁的一些可能性。
谁能帮我?
编辑:
我有一个例子:
main.cpp:
#include "thread.hpp"
#include <iostream>
int main() {
std::mutex mutex;
ThreadPool pool(4, 100);
for (int i = 0; i < 10000; ++i)
pool.push([&mutex, i] {
mutex.lock();
std::cout << "thread n. " << i << '\n';
mutex.unlock();
});
return 0;
}