Проблема с TerminateThread

230
17 июля 2017, 16:06

Создаю поток.

connect = new thread(&startWaitConnect,this);
connect->detach();

Потом вызываю connect->native_handle() и получаю 0. TerminateThread((HANDLE) connect->native_handle(), 0) возвращает ошибку 6. При этом сам native_handle возвращает long long а не HANDLE. Приходиться выполнять приведение типа. Это нормально?

Answer 1

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

Если вы собираетесь как-то управлять потоком - не используйте detach.

PS TerminateThread - это очень плохая идея, заверенный таким образом поток оставит много незакрытых ресурсов и мусора в памяти. Лучше придумайте способ кооперативного завершения.

Например, если поток работает с сокетом - то можно закрыть этот сокет.

Answer 2

Вообще-то native_handle() возвращает native_handle_type - тип, зависящий от реализации. Например, в VC++ это

typedef void *native_handle_type;

и точно так же определен тип

typedef void *HANDLE;

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

Но это в вашем случае, увы, не играет особой роли, так как, поскольку вам возвращается значение 0, похоже, native_handle() не возвращает корректный дескриптор (возможно, поток уже завершился?). В стандарте сказано

30.2.3 Native handles [thread.req.native]
Several classes described in this Clause have members native_handle_type and native_handle. The presence of these members and their semantics is implementation-defined. [ Note: These members allow implementations to provide access to implementation details. Their names are specified to facilitate portable compile-time detection. Actual use of these members is inherently non-portable. —end note ]

то есть все зависит от вашего конкретного компилятора. Так что вам нужно обратиться к его документации по поводу приведения типа. Допускаю даже, что не слишком умный компилятор мог сделать просто "затычку", всегда возвращающую нуль :) - но это вряд ли...

Далее, я бы сказал, что смешивать использование API для работы с потоками и стандартные функции - не слишком-то хорошо. Или дожидайтесь окончания с помощью join(), или вообще забудьте о потоке - для этого, собственно, и служит detach(). Для чего вам заставлять форсированно завершаться отключенный поток (фактически не позволяя выполнить все очищающие процедуры)? Что вы хотите этим добиться? Почему этого нельзя добиться средствами стандарта?

READ ALSO
Большие проблемы с загрузкой tmx-файлов

Большие проблемы с загрузкой tmx-файлов

ЗдравствуйтеНеобходимо загрузить и отрисовать карту в tmx-формате

325
выброс исключения без имени

выброс исключения без имени

Почему не отлавливается исключение?

289
Написание программы под Linux (Orange Pi)

Написание программы под Linux (Orange Pi)

Добрый деньНеобходимо написать программу, которая будет запускаться в Debian на устройстве Orange Pi

371