Thread join detach
От: Максим Рогожин Россия  
Дата: 10.06.18 16:40
Оценка:
Привет!

void thread_func();
void some_func();

int main() {
   std::thread t(thread_func);
   some_func();
   t.join();
}


К моменту вызова t.join() поток t уже мог завершиться, но тем не менее по стандарту все равно требуется вызвать либо join() либо detach() перед деструктором std::thread — иначе деструктор std::tread зовет std::terminate(). Объясните, пожалуйста, почему такое требование?
Re: Thread join detach
От: Слава  
Дата: 10.06.18 18:25
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>К моменту вызова t.join() поток t уже мог завершиться, но тем не менее по стандарту все равно требуется вызвать либо join() либо detach() перед деструктором std::thread — иначе деструктор std::tread зовет std::terminate(). Объясните, пожалуйста, почему такое требование?


Чтобы не плодились ничейные висячие треды, очевидно. Этакий предохранитель.
Re[2]: Thread join detach
От: Максим Рогожин Россия  
Дата: 10.06.18 18:42
Оценка:
Здравствуйте, Слава, Вы писали:

С>Чтобы не плодились ничейные висячие треды, очевидно. Этакий предохранитель.


Почему висячие, если поток уже завершился?
Re[3]: Thread join detach
От: Слава  
Дата: 10.06.18 18:59
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Почему висячие, если поток уже завершился?


Откуда ему, объекту ссылающемуся на поток, знать что он завершился? Это только в рантайме может выясниться. Насколько я знаю, от применения Terminate к уже завершённому потоку, никаких проблем быть не должно — если пользоваться WinApi. В С++ обёртке может быть и по-другому (тут я не знаю точно), например вызывается GetLastError, он выдаёт ненулевой результат и из-за того выбрасывается исключение.
Re[4]: Thread join detach
От: Максим Рогожин Россия  
Дата: 11.06.18 09:54
Оценка:
Здравствуйте, Слава, Вы писали:

С>Откуда ему, объекту ссылающемуся на поток, знать что он завершился? Это только в рантайме может выясниться. Насколько я знаю, от применения Terminate к уже завершённому потоку, никаких проблем быть не должно — если пользоваться WinApi. В С++ обёртке может быть и по-другому (тут я не знаю точно), например вызывается GetLastError, он выдаёт ненулевой результат и из-за того выбрасывается исключение.


std::terminate() вызывает завершение всей программы. Если бы дело было только в висячих потоках — это была бы просто утечка ресурсов. Не обязательно было бы программу завершать.
Re: Thread join detach
От: sergii.p  
Дата: 12.06.18 07:06
Оценка:
Здравствуйте, Максим Рогожин, Вы писали:

МР>Привет!


МР>
МР>void thread_func();
МР>void some_func();

МР>int main() {
МР>   std::thread t(thread_func);
МР>   some_func();
МР>   t.join();
МР>}
МР>


МР>К моменту вызова t.join() поток t уже мог завершиться, но тем не менее по стандарту все равно требуется вызвать либо join() либо detach() перед деструктором std::thread — иначе деструктор std::tread зовет std::terminate(). Объясните, пожалуйста, почему такое требование?


во-первых, перед t.join() надо выполнить проверку t.joinable() иначе можем вылететь с исключением,
во-вторых, стандарт не может решить за программиста, какое поведение потока ему нужно. join() может повесить программу, detach() запросто может привести к висячим ссылкам. Вызов terminate() видимо показалось меньшим из зол Но никто не мешает написать свою RAII обёртку, которая будет вызывать join автоматом.
class thread_wrapper
{
private:
    std::thread thread;
public:
    thread_wrapper(std::thread thread) { this->thread = std::move(thread); }
    ~thread_wrapper() { if(thread.joinable()) thread.join(); }
};
Re[2]: Thread join detach
От: Максим Рогожин Россия  
Дата: 12.06.18 15:04
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>во-вторых, стандарт не может решить за программиста, какое поведение потока ему нужно. join() может повесить программу, detach() запросто может привести к висячим ссылкам. Вызов terminate() видимо показалось меньшим из зол


Если на момент вызова деструктора std::thread поток еще не завершился, то компилятор не может за программиста решить ждать завершения потока или нет.

Но если на момент вызова деструктора std::thread поток уже завершился, то зачем в этом случае звать std::terminate()?
Re[3]: Thread join detach
От: wander  
Дата: 12.06.18 19:22
Оценка: 2 (1)
Здравствуйте, Максим Рогожин, Вы писали:

МР>Но если на момент вызова деструктора std::thread поток уже завершился, то зачем в этом случае звать std::terminate()?


В этом запуске поток завершился, в следующем не успел. В этот раз программа не вызвала terminate, в следующий — вызвала. Потом 10 раз подряд не вызвала, а на 11 — вызвала.
Вам самому понравилось бы такое плавающее поведение?
Уж лучше один раз установить контракт, а не делать его зависимым от фазы луны.
Re: Thread join detach
От: reversecode google
Дата: 12.06.18 20:03
Оценка: -1
когда книжка с вопросами по собеседованию закончится или у вас там еще пачка запасена ?
еще лет на 5 хватит спамить по форуму ?
Re[3]: Thread join detach
От: sergii.p  
Дата: 13.06.18 10:53
Оценка: 2 (1)
Здравствуйте, Максим Рогожин, Вы писали:

МР>Если на момент вызова деструктора std::thread поток еще не завершился, то компилятор не может за программиста решить ждать завершения потока или нет.


МР>Но если на момент вызова деструктора std::thread поток уже завершился, то зачем в этом случае звать std::terminate()?


мне кажется, это можно было реализовать, но несколько усложнило бы логику работы. Получается созданному потоку надо будет информировать связанный класс std::thread о своём завершении. Это делается ради одного конкретного случая (несколько странного — фактически это эквивалентно вызову detach, но только без явного указания). Видимо намного проще написать в документации, что нужно всегда вызывать либо detach, либо join
Re: Thread join detach
От: Mr.Delphist  
Дата: 13.06.18 15:01
Оценка: 2 (1)
Здравствуйте, Максим Рогожин, Вы писали:

МР>К моменту вызова t.join() поток t уже мог завершиться, но тем не менее по стандарту все равно требуется вызвать либо join() либо detach() перед деструктором std::thread — иначе деструктор std::tread зовет std::terminate(). Объясните, пожалуйста, почему такое требование?


Гуглим и читаем раз:
http://en.cppreference.com/w/cpp/thread/thread/detach

Гуглим и читаем два:
https://tproger.ru/problems/safe-threads-in-cpp/

Следующие вопросы лучше задавать на StackOverflow.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.