Использование cout в нескольких потоках может привести к перемежению вывода.
Поэтому я попытался защитить cout с помощью мьютекса.
Следующий код запускает 10 фоновых потоков с std :: async. Когда начинается поток, он печатает "Начальный поток...". Основной поток выполняет итерацию фьючерсов фоновых потоков в том порядке, в котором они были созданы, и распечатывает "Done thread...", когда соответствующий поток завершен.
Выход синхронизируется правильно, но после того, как некоторые потоки запущены, а некоторые закончили (см. Вывод ниже), возникает тупик. Все фоновые потоки слева и основной поток ждут мьютекс.
В чем причина тупика?
Когда функция печати оставлена или одна итерация цикла for завершается, lock_guard должен разблокировать мьютекс, чтобы один из ожидающих потоков мог продолжить.
Почему все нити остались голодными?
Код
#include <future>
#include <iostream>
#include <vector>
using namespace std;
std::mutex mtx; // mutex for critical section
int print_start(int i) {
lock_guard<mutex> g(mtx);
cout << "Started thread" << i << "(" << this_thread::get_id() << ") " << endl;
return i;
}
int main() {
vector<future<int>> futures;
for (int i = 0; i < 10; ++i) {
futures.push_back(async(print_start, i));
}
//retrieve and print the value stored in the future
for (auto &f : futures) {
lock_guard<mutex> g(mtx);
cout << "Done thread" << f.get() << "(" << this_thread::get_id() << ")" << endl;
}
cin.get();
return 0;
}
Выход
Started thread0(352)
Started thread1(14944)
Started thread2(6404)
Started thread3(16884)
Done thread0(16024)
Done thread1(16024)
Done thread2(16024)
Done thread3(16024)