Деструкторы потоков в С++ 0x против boost
В эти дни я читаю pdf Проектирование MT-программ. В нем объясняется, что пользователь ДОЛЖЕН явным образом вызывать detach()
для объекта класса std::thread
в С++ 0x до того, как этот объект выходит из области видимости. Если вы его не назовете, будет вызван std::terminate()
, и приложение умрет.
Обычно я использую boost::thread
для потоковой обработки в С++. Исправьте меня, если я ошибаюсь, но объект boost::thread
автоматически отделяется, когда он выходит из области видимости.
Мне кажется, что подход с усилением следует принципу RAII, а std - нет.
Знаете ли вы, есть ли какая-то особая причина для этого?
Ответы
Ответ 1
Это действительно так, и этот выбор объясняется в N3225 запиской о std::thread
деструкторе:
Если joinable()
, то terminate()
, в противном случае никаких эффектов. [ Заметка: Либо неявное отстранение или присоединение a joinable()
в своей деструктор может отлаживать правильность (для отсоединения) или ошибки производительности (для присоединения) встречается только тогда, когда исключение поднял. Таким образом, программист должен убедитесь, что деструктор никогда выполняется, пока поток все еще присоединяемые. -end note]
Очевидно, комитет пошел на меньшее из двух зол.
EDIT Я только что нашел эту интересную статью, которая объясняет, почему первоначальная формулировка:
Если joinable()
, то detach()
, в противном случае никаких эффектов.
был изменен для ранее указанного.
Ответ 2
Здесь один из способов реализации потоков RAII.
#include <memory>
#include <thread>
void run() { /* thread runs here */ }
struct ThreadGuard
{
operator()(std::thread* thread) const
{
if (thread->joinable())
thread->join(); // this is safe, but it blocks when scoped_thread goes out of scope
//thread->detach(); // this is unsafe, check twice you know what you are doing
delete thread;
}
}
auto scoped_thread = std::unique_ptr<std::thread, ThreadGuard>(new std::thread(&run), ThreadGuard());
Если вы хотите использовать это для отсоединения потока, прочитайте это в первую очередь.