std:: thread C 11 не может объяснить мне, почему

#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:

Это просто классическая тупиковая ситуация: основной поток получает блокировку, а затем блокируется при присоединении к другому потоку, но другой поток может присоединиться, только если ему удастся получить блокировку.