Предположим, что существует ряд потоков, которые состоят из циклов, запускающих экземпляры одной и той же функции, но начало каждой итерации необходимо синхронизировать (так что потоки, которые заканчиваются сначала, должны ждать, пока последний начнет новую итерацию). Как это можно сделать в C++ 11?Как синхронизировать экземпляры функции, выполняющейся на разных потоках (в C++ 11)?
...
Остальная часть поста только то, что я пытался, и как она выходит из строя.
Я использую счетчик «sync», изначально установленный на 3 (количество потоков). Каждый поток, в конце функции, вычитает 1 из этого счетчика и начинает ждать. Когда счетчик достигает 0, это означает, что 3 из них закончили один раунд, поэтому основной поток сбросит счетчик на 3 и сообщит о потоках, чтобы разбудить их.
Это работает большую часть времени, но иногда один или два потока не могут проснуться.
Так что эти глобальные переменные:
mutex syncMutex;
condition_variable syncCV;
int sync;
Это в конце функции, которая выполняется в цикле в резьбе:
unique_lock<mutex> lk(syncMutex);
cout << "Thread num: " << mFieldNum << " got sync value: " << sync;
sync --;
syncCV.notify_all();
cout << " and goes to sleep..." << endl;
syncCV.wait(lk, []{return sync == numFields;});
cout << "Thread num: " << mFieldNum << " woke up" << endl;
}
И это работает в цикле в основной поток:
unique_lock<mutex> lk(syncMutex);
syncCV.wait(lk, []{return sync == 0;});
sync = 3;
lk.unlock();
cout << "Notifying all threads!" << endl;
syncCV.notify_all();
Это выход он производит, когда он выходит из строя (поток # 3 не просыпаются):
Thread num: 1 got sync value: 3 and goes to sleep...
Thread num: 2 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 1 woke up
Thread num: 2 woke up
Thread num: 3 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 2 woke up
Thread num: 1 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
У кого-нибудь есть ключ? Спасибо за чтение.
Поскольку каждый поток выполняется в цикле, после того, как поток 1 или 2 просыпался, sync-- был выполнен, прежде, чем нити 3 [] {возвращение синхронизации == numFields;} предикат был выполнен. Предикат был оценен как false, поэтому поток 3 не проснулся. –
Спасибо @TonyJ Знаете ли вы, как это можно исправить? – siflun