我正在开发一个程序,它从几个搜索文件系统的线程打印正则表达式匹配,每个线程将其id添加到队列,并通知主线程有一些线程要从线程池中删除,这是一个std: :向量。
此时,每当我执行时,我都会解锁并锁定互斥锁 对要保护的资源的操作。感觉就像我 想到这一切都是错的,而且我太过细化了。将 最好在进入while循环之前锁定互斥锁,解锁 它弹出队列后,然后再锁定它 !下一次迭代会调用finished_threads.empty()吗?
void RegexSearch::Run()
{
running = true;
search_pool.push_back(std::thread([&] { StartPrint(); }));
/*
Get directories and create another thread for each subdirectory while there are
less threads than maximum in the pool.
*/
fs::path searchDir(directory);
for (const auto& dir : searchDir)
{
if (search_pool.size() >= MAX_THREADS)
{
std::unique_lock<std::mutex> lck(mu, std::defer_lock);
// Wait to be notified that thread is finished execution and another can start.
max_thread_cond.wait(lck);
lck.lock();
while (!finished_threads.empty())
{
lck.unlock();
lck.lock();
std::thread::id remove_thread = finished_threads.front();
lck.unlock();
lck.lock();
finished_threads.pop();
lck.unlock();
std::remove_if(search_pool.begin(), search_pool.end(), [&remove_thread](const std::thread::id &t) { return remove_thread == t; });
lck.lock();
}
}
}
}
答案 0 :(得分:1)
您必须在!empty()
的测试中保持锁定,直到您从队列中删除该项目为止。否则几个线程可能会尝试删除相同的项目 - 也许是最后一个。
我也看到函数开头的push_back
没有受到保护。如果可能有多个线程访问search_pool
,那么它也必须受到保护。