Я пытаюсь понять несколько базовых понятий в std::thread
, в которых я все еще не уверен.Основной вопрос:
что на самом деле происходит, когда я превышаю значение std::thread::hardware_concurrency()
, как я это делал ниже?
Я знаю, что метод это просто подсказка, но в этом случае 8 должно быть точным.Я не вижу предупреждений или ошибок, так что же на самом деле происходит?
Я подозреваю, что это как-то связано с моим непониманием join()
и detach()
, что приводит меня ко второму вопросу.
Я знаю, что если я раскручиваю потоки без join()
или detach()
, я получу ошибки во время выполнения.Как я понял из чтения и наблюдений, join()
заставляет поток блокироваться до тех пор, пока он не завершит выполнение, в то время как detach()
делает в основном обратное, позволяя потоку дичать до завершения, потенциально открывая банку с червями, если этопоток не завершается сам по себе.
Исходя из того, что я заметил, кажется, что использование join()
и detach()
являются взаимоисключающими.Это неправильно?Зачем мне когда-либо использовать join()
и detach()
в одной и той же теме?
Что касается моего первого вопроса, я даже не могу догадаться.Я ожидал какой-то тип ошибки во время выполнения или более очевидную принудительную блокировку.
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <vector>
std::vector<unsigned> getNumbers(unsigned n)
{
std::vector<unsigned> out;
while(n > 0)
{
out.push_back(rand());
n--;
}
return out;
}
int main() {
srand(time(nullptr));
std::vector<std::thread> threads;
unsigned maxThreads = std::thread::hardware_concurrency();
std::cout << "Max threads: " << maxThreads << std::endl;
unsigned tooManyThreads = maxThreads + 5;
for(auto i = 0; i < tooManyThreads; i++)
{
threads.push_back(std::thread(getNumbers,(rand() % 10000 + 1)));
std::cout << "Starting thread " << i << " ("
<< threads.back().get_id() << ")" << std::endl;
threads.back().detach();
}
for(auto i = 0; i < tooManyThreads; i++)
{
if(threads.at(i).joinable())
{
threads.at(i).join();
std::cout << "Joining " << i << std::endl;
}
}
return 0;
}