30. Семафоры и мьютексы (SystemV IPC, POSIX pthread IPC). Синхронизация потоков Unix/Linux: join и joinable-потоки. Обработка множественных запросов: подходы к построению серверов.

Все дело в том что главная функция программы main создает объект func_thread, с параметром конструктора anyFunc и продолжает свое выполнение не дожидаясь чтобы процесс закончился, что и вызывает ошибку времени выполнения. Чтобы ошибки не было надо чтобы до того как закончится функция main все потоки были закончены. Это осуществляется путем синхронизации потоков вызывая метод join. Метод join возвращает выполнение программе когда поток заканчивается, после чего объект класса thread можно безопасно уничтожить.

#include<iostream> 
#include<thread> //Файл в котором определен класс thread 
using namespace std; 
 
void anyFunc() { 
    cout << "thread function"; 
} 
 
int main() { 
    thread func_thread(anyFunc); 
    func_thread.join();  
    // Выполнение возвращается функции main когда поток заканчивается 
    return 0; 
}

Позвольте добавить что перед вызовом функции join надо проверить является ли объект joinable то есть представляет он реальный поток или нет, к примеру объект может быть объявлен но не инициализирован или уже закончен вызовом функции join. Проверка делается функцией joinable, который возвращает true в случае если объект представляет исполняемый поток и false в противном случаи. Надо отметить что может быть ситуация когда нам ненужно ждать чтобы поток закончился, для этого у класса thread есть другой метод по имени detach. Обе метода ничего не принимают и не возвращают и после их вызова объект становится not joinable и можно безопасно уничтожить.