Очистка при выходе из нити - PullRequest
1 голос
/ 02 мая 2011

Когда мой поток выходит, его дескриптор должен быть закрыт и сброшен в NULL.Вместо того, чтобы делать это при событии закрытия потока (например, ::WaitForSingleObject( s_hMyThread, TIMEOUT );), будет ли правильным закрыть дескриптор и сбросить его как самую последнюю вещь в потоке, прежде чем он вернется, как это?

DWORD MyThread( LPVOID pParam )
{
    // Does something...

    ::CloseHandle( s_hMyThread );
    s_hMyThread = NULL;

    return 0;
}

Ответы [ 4 ]

4 голосов
/ 02 мая 2011

Вы можете сделать это.

Закрытие дескриптора потока не завершает связанный поток или не удаляет объект потока.Объект потока остается в системе до тех пор, пока поток не прекратится и все его дескрипторы не будут закрыты посредством вызова CloseHandle.

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

0 голосов
/ 04 мая 2011

После прочтения вашего комментария к ответу Лиора Когана ( "Обсуждаемая нить выполнена в виде одиночного броска для обработки некоторых вещей, которые в противном случае блокировали бы приложение, поэтому, как только это будет сделано, это будет сделано." ), мне кажется, что вы вообще не интересуетесь этой ручкой.

Почему тогда вы не CloseHandle(CreateThread(...));?Это вполне допустимо.

Или еще лучше, используйте _beginthread и _endthread.Это будет работать, даже если вы do интересуетесь этим потоком и, например, хотите дождаться его завершения.
Из документации: "_endthread автоматически закрывает дескриптор потока (тогда как _endthreadex этого не делает)Поэтому при использовании _beginthread и _endthread не закрывайте дескриптор потока явно, вызывая Win32 CloseHandle API. "

Не нужно беспокоиться о закрытии чего-либо, и у него есть дополнительное преимущество, заключающееся в отсутствии утечек при сломанных реализациях CRT.

0 голосов
/ 02 мая 2011

Технически это действительно. Вы можете закрыть этот дескриптор так же, как любой другой дескриптор - в любом потоке, который вам нравится.

Но закрывать дескриптор потока, как вы делали в вашем примере, не очень хорошая идея - это вообще бессмысленно и может быть небезопасно, потому что нет никакой правильной синхронизации при доступе к переменной s_hMyThread. Конечно, вы могли бы сделать правильную синхронизацию вашей переменной s_hMyThread, но это был бы слишком сложный для поддержки код без реальной цели на самом деле. Нет смысла закрывать дескриптор потока из этого самого потока, потому что единственная причина держать дескриптор потока открытым - это ожидание где-нибудь завершения этого потока, что, естественно, подразумевает, что дескриптор должен оставаться открытым после завершения потока.

Обычно хорошей практикой является (1) если вам не нужно ждать завершения потока, затем вы закрываете его дескриптор на следующей строке после его создания (следующий вызов после CreateThread), (2) если вам нужно ждать завершения этого потока затем вы закрываете дескриптор потока, когда знаете, что объект потока сигнализируется (т.е. поток завершен). Я не вижу других применений, когда вам действительно нужна ручка потока.

0 голосов
/ 02 мая 2011

Мне не ясно, что это оставит объект потока в состоянии, когда любой, кто его ожидает, может определить, что происходит.Согласно документам :

Когда поток завершается, объект потока достигает сигнального состояния, удовлетворяя любые потоки, которые ожидали на объекте.

Я подозреваю, что вы получите дескриптор потока, возвращенный из CreateThread, но созданный поток закроет этот дескриптор.Кажется, противоречит замыслу разработки API, нет?Независимо от того, работает ли это, я бы не стал этого делать, если это не важно для вашего дизайна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...