gpt4 book ai didi

c++ - 线程池(大概)锁定条件变量和互斥量的问题

转载 作者:行者123 更新时间:2023-11-28 04:47:02 26 4
gpt4 key购买 nike

我在处理线程池时遇到了一个关于条件变量和互斥锁的奇怪问题。我怀疑可能存在锁定问题,因为它有时有效,有时无效。这是代码的相关部分(删除了不相关的位):

class ThreadPool {
private:
std::atomic<bool> running;
std::atomic<size_t> unfinished_tasks;
std::queue<std::function<void(void)>> task_queue;
std::condition_variable cv_work;
std::mutex mtx_queue;
std::vector<std::thread> threads;

public:
ThreadPool(size_t num_threads = std::thread::hardware_concurrency());
~ThreadPool();

template<class T, class Fn>
std::future<T> queueTask(Fn&& fn);
};

ThreadPool::ThreadPool(size_t num_threads) :
running(true), unfinished_tasks(0) {
auto thread_loop = [&] {
while (running.load()) {
std::unique_lock<std::mutex> lock(mtx_queue);
if (!task_queue.empty()) {
auto work = task_queue.front();
task_queue.pop();
lock.unlock();
work();
unfinished_tasks--;
} else {
std::cout << std::this_thread::get_id() << " going to sleep..." << std::endl;
cv_work.wait(lock);
}
}};
threads.reserve(num_threads);
for (size_t i = 0; i < num_threads; i++) {
threads.push_back(std::thread(thread_loop));
}
}

template<class T, class Fn>
inline std::future<T> ThreadPool::queueTask(Fn&& fn) {
// func = lambda containing packaged task with fn
mtx_queue.lock();
task_queue.push(func);
mtx_queue.unlock();
unfinished_tasks++;
cv_work.notify_one();
return future;
}

一旦我注释掉包含调试输出的行,向线程池添加大量小任务将使它在某个时刻锁定,在调试输出到位的情况下,它将正确完成所有任务。我不太确定问题出在哪里。

最佳答案

您有竞争条件。 queueTask 可以在您的线程函数等待之前通知cv_work。在调用 cv_work.notify_one() 之前,不要解锁 mtx_queue

关于c++ - 线程池(大概)锁定条件变量和互斥量的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49088175/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com