std::thread завершается до того, как я могу его отсоединить

Если я создам std::thread, который завершится до того, как я смогу вызвать для него detatch(), каково ожидаемое поведение? Следует ли генерировать исключение из-за того, что joinable уже является ложным?

Если это так, то есть ли способ создать поток, который инициализируется в отсоединенном состоянии, чтобы я мог избежать этой ошибки?

Пример:

void func()
{
    // do something very trivial so that it finishes fast
    int a = 1;
}

void main()
{
    thread trivial(func);
    trivial.detach();
}

Я понимаю, что на практике нецелесообразно создавать поток для выполнения тривиальной работы, однако мне удалось столкнуться с таким поведением, и мне было любопытно узнать, есть ли способ обойти это...


person Michael Landes    schedule 10.12.2014    source источник
comment
Результат joinable() не зависит от того, завершил ли поток выполнение. В вашем сценарии joinable() на самом деле не станет false, пока вы не вызовете detach(). Здесь нет проблем, нуждающихся в обходном пути.   -  person Igor Tandetnik    schedule 10.12.2014
comment
Хорошие моменты. Я получаю такое поведение в Visual Studio 2012. Возможно, какая-то ошибка оптимизации?   -  person Michael Landes    schedule 10.12.2014
comment
Цитата Алекса Фарбера взята из en.cppreference.com/w/cpp/thread/thread /присоединяемый   -  person Gabriel    schedule 30.12.2014


Ответы (2)


Присоединение и отсоединение имеют одно и то же требование, они должны быть присоединяемыми. Поэтому я думаю, что выполнения проверки соединения должно быть достаточно.

If(trivial.joinable())
    trivial.detach();

В документации указано:

Поток, который завершил выполнение кода, но еще не был присоединен, по-прежнему считается активным потоком выполнения и, следовательно, может быть присоединен.

Поэтому я предполагаю, что отсоединенный поток сразу же перестанет существовать. Но его определенно можно создать.

Примечание. Рекомендуется всегда вызывать joinable() перед присоединением к цепочке или отключением от нее.

person laurisvr    schedule 15.05.2015
comment
Это, конечно, содержит состояние гонки, поскольку оно может стать неприсоединимым после проверки, но до отсоединения. - person jcoder; 12.08.2015
comment
@jcoder Это было бы правдой, если бы протектор тем временем перестал соединяться. Как вы себе это представляете? - person laurisvr; 12.08.2015

Объект потока будет уничтожен, когда его область действия будет завершена. Чтобы убедиться, что объект завершил свою работу, вам нужно либо вызвать соединение, либо отсоединиться.

person Tomas    schedule 12.08.2015