Я работаю над программой, которая печатает регулярные выражения из нескольких потоков, ищущих файловую систему, и каждый поток добавляет свой идентификатор в очередь и уведомляет основной поток о том, что есть некоторые потоки, которые нужно удалить из пула потоков который является std :: vector.Правильная гранулярность для блокировки Mutex
В этот момент я отпираю и блокирую мьютексы всякий раз, когда выполняю операцию над ресурсом, который необходимо защитить. Мне кажется, что я чувствую, что все это неправильно, и что я слишком разборчив. Будет ли лучше блокировать мьютексы перед входом в цикл 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();
}
}
}
}
О, это имеет смысл. Нет потоков, обращающихся к thread_pool до вызова Run(). Нужно ли это блокировать с помощью мьютекса? – CanadaIT
Стандартные контейнеры не являются потокобезопасными, поэтому, если больше потоков может получить доступ к контейнеру во время его обновления, должна быть блокировка. Если вы только читаете или есть только один поток, обращающийся к определенному контейнеру, вы все равно в безопасности. –