#multithreading #c 11
#многопоточность #c 11
Вопрос:
Я запускаю эту очень простую программу на рабочем столе Ubuntu 13.04, однако, если я закомментирую строку sleep_for, она зависает после печати cout из main. Кто-нибудь может объяснить, почему? Насколько я понимаю, main — это поток, а t — другой поток, и в этом случае мьютекс управляет синхронизацией для общего объекта cout.
#include <thread>
#include <iostream>
#include <mutex>
using namespace std;
std::mutex mu;
void show()
{
std::lock_guard<mutex> locker(mu);
cout<<"this is from inside the thread"<<endl;
}
int main()
{
std::thread t(show);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::lock_guard<mutex> locker(mu);
cout<<"This is from inside the main"<<endl;
t.join();
return 0;
}
Комментарии:
1. Это причина общего требования к качеству кода, согласно которому любой объект, деструктор которого имеет побочные эффекты, должен создаваться в начале области видимости, если только нет веской причины поступить иначе.
Ответ №1:
Если вы измените на main
функцию следующим образом, код будет работать так, как ожидалось:
int main()
{
std::thread t(show);
{
std::lock_guard<mutex> locker(mu);
cout << "This is from inside the main" << endl;
} // automatically release lock
t.join();
}
В вашем коде есть неудачное условие гонки. Если поток t
получает блокировку первым, все работает нормально. Но если основные потоки получают блокировку первыми, она удерживает блокировку до конца main
функции. Это означает, что поток t
не имеет шансов получить блокировку, не может завершиться, и основной поток будет заблокирован t.join()
.
Ответ №2:
Это просто классическая тупиковая ситуация: основной поток получает блокировку, а затем блокируется при присоединении к другому потоку, но другой поток может присоединиться, только если ему удастся получить блокировку.