с++: ожидание события некоторыми потоками
подскажите как реализовать функциями из stl следующую задачу:
у меня потокам раздаются последовательно задачи (задачу упростил чтобы много кода не писать):
void mythread::thread_func(...)
{
while (true)
{
// получить задачу
m_lock.lock();
const int index = m_global_index;
m_global_index ++;
m_lock.unlock();
// выполнить задачу
}
ТОЛЬКО (!!!) когда все задачи выполнены начинают выдаваться следующие задачи
возможна ситуация, когда один поток еще выполняет последнюю задачу, а новый поток уже хочет получить следующую, но пока задач нет ему надо подождать
подскажите как это корректно реализовать?
т.е. должно быть что-то на подобии:
void mythread::thread_func(...)
{
while (true)
{
// получить задачу
m_lock.lock();
// если старых задач уже не осталось, но они еще не выполнены всеми потоками - подождать
if (m_global_index > m_max_index)
std::wait(....); // какая-то функция, позволяющая подождать события
const int index = m_global_index;
m_global_index ++;
m_lock.unlock();
// выполнить задачу
// если это была последняя задача - сгенерировать событие для запуска с ожидания остальных потоков
}
Ответы (1 шт):
std::condition_variable block;
std::condition_variable last;
bool need_to_wait;
void mythread::thread_func(...)
{
while (true)
{
// получить задачу
m_lock.lock();
// если старых задач уже не осталось, но они еще не выполнены всеми потоками - подождать
if (m_global_index == m_max_index) {
last.notify_one(); // сообщаем о том что это последняя задача
need_to_wait = true;
}
const int index = m_global_index;
m_global_index ++;
if (need_to_wait) {
work(...);
need_to_wait = false;
block.wait(...);
m_lock.unlock();
} else {
m_lock.unlock();
work(...);
}
}
}
В общих чертах как-то так.
А там где нужно будет поставлять новые задачи подайте сигнал на block. Тогда тот последний выполнит свою работу и будет ждать новых поступлений, а все остальные будут ждать пока не разлочится мьютекс.
Получили задачу
Проверили нужно ли ждать
2.1) Если не нужно, последняя ли задача, установили значение ожидания на истину
2.2) Начали ждать
2.3) Дождались, продолжаем работу
Работаем
Сообщаем о том что ждать больше не нужно, устанавливается значение переменной ожидания на ложь, если это была последняя задача.