деструкторы потоков в C ++ 0x против boost - PullRequest
13 голосов
/ 22 декабря 2010

В эти дни я читаю pdf Проектирование программ MT .Это объясняет, что пользователь ДОЛЖЕН явно вызвать detach() для объекта класса std::thread в C ++ 0x, прежде чем этот объект выйдет из области видимости.Если вы не позвоните, будет вызвано std::terminate(), и приложение умрет.

Я обычно использую boost::thread для многопоточности в C ++.Поправьте меня, если я ошибаюсь, но объект boost::thread автоматически отсоединяется, когда выходит из области видимости.

Мне кажется, что подход повышения основан на принципе RAII, а стандарт - нет.

Знаете ли вы, есть ли для этого какая-то особая причина?

Ответы [ 2 ]

16 голосов
/ 22 декабря 2010

Это действительно так, и этот выбор объясняется в N3225 на примечании, касающемся std::thread деструктора:

Если joinable(), то terminate(), в противном случае никаких эффектов. [ Примечание: Либо неявно отсоединение или присоединение joinable() поток в его деструктор может привести к трудностям отладить правильность (для отсоединения) или ошибки производительности (для соединения) встречаются только тогда, когда исключение поднял. Таким образом, программист должен убедитесь, что деструктор никогда выполняется, пока поток еще объединяемые . —конечная записка ]

Очевидно, комитет пошел на меньшее из двух зол.


РЕДАКТИРОВАТЬ Я только что нашел эту интересную статью , которая объясняет, почему первоначальная формулировка:

Если joinable(), то detach(), иначе никаких эффектов.

было изменено на ранее указанное.

3 голосов
/ 28 февраля 2013

Вот один из способов реализации потоков 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());

Если вы хотите использовать это для отсоединения потока, сначала прочтите это .

...