Как лучше всего убить зависший поток?

Рейтинг: 4Ответов: 4Опубликовано: 07.04.2015
std::thread * tr1;
tr1 = new std::thread([&]()
{
    function();     // функция что то считает
    Sleep(3000000); // допустим это означает зависание
});

Запущенный поток по каким то причинам завис, таймер определил, что поток выполняется дольше времени. Как можно убить поток, чтобы он не висел в памяти и не выполнял вычисления? В потоке нет никаких мьютексов и.т.д. Никакие переменные разрушится не смогут, туда передаётся указатель, который при обнаружении что таймер превышен задается в ноль. Больше поток ни с кем и ни с чем не контактирует.

Как его можно убить или поставить на паузу?

Ответы

▲ 2Принят

Если на винде, то

TerminateThread(tr1->native_handle,0);

используйте на свой страх и риск :D

▲ 12

std::thread не поддерживает данную фичу, потому что так делать крайне не рекомендуется. Если у вас повис поток, это уже плохо, и именно эту проблему надо исправлять, а не пытаться городить костыли с убийствами потоков.

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

Если вам нужны убиваемые потоки, то можете воспользоваться boost::thread. Или доковыряться до нативного хэндла std::thread::naitive_handle и воспользоваться специфичными для оси функциями.

▲ 6

Потоки убивать нельзя.

  1. Поток взаимодействует с другими потоками, которые могут ждать каких то действий от убиваемого потока и убийство приведёт к взаимоблокировке (deadlock). Например: второй поток ждёт вызова SetEvent(), которого не произойдёт.

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

  3. Поток может работать с файлом, который так же останется в несогласованном состоянии (запись не будет завершена и файл будет испорчен).

  4. Как правило у длительных блокирующих операций ввода-вывода есть возможность прервать выполнение, вызывать их асинхронно, использовать неблокирующее API и т.п. Например: вызывать select или poll с коротким временем ожидания, и в цикле проверять не пришёл ли запрос на остановку. Можно открыть pipe и добавить его дескриптор в набор FD_SET для select() и когда понадобиться написать что нибудь в pipe для возврата из вызова select().

▲ 2

если очень хочется то можно вызвать деструктор объекта, например используя умный указатель, код будет выглядить примерно так:

std::unique_ptr <str::thread> tr1 (new std::thread([&]()
{
function();     // функция что то считает
Sleep(3000000); // допустим это означает зависание
}));

if( tr1.joinable() )    // проверим, что поток запущен
    tr1.clear();        // в деструкторе потока вызовится метод terminate()

документация