|
|
||
3. Завершение потоков |
||
Поток завершается вызовом функции ExitThread, которая имеет следующий прототип: Эта функция может вызываться как явно, так и неявно при возврате значения из функции потока. При выполнении этой функции система посылает динамическим библиотекам, которые загружены процессом, сообщение DLL_THREAD_DETACH, которое говорит о том, что поток завершает свою работу. Один поток может завершить другой поток, вызвав функцию В случае успешного завершения функция TerminateThread возвращает ненулевое значение, в противном случае — FALSE. Функция TerminateThread завершает поток, но не освобождает все ресурсы, принадлежащие этому потоку. Это происходит потому, что при выполнении этой функции система не посылает динамическим библиотекам, загруженным процессом, сообщение о том, что поток завершает свою работу. В результате динамическая библиотека не освобождает ресурсы, которые были захвачены для работы с этим потоком. Поэтому эта функция должна вызываться только в аварийных ситуациях при зависании потока. В листинге 3.3 приведена программа, которая демонстрирует работу функции TerminateThread. В этой программе следует обратить внимание на квалификатор типа volatile, который указывает компилятору, что значение переменной count должно храниться в памяти, т. к. к этой переменной имеют доступ параллельные потоки. Дело в том, что сам компилятор языка программирования С или C++ не знает, что такое поток. Для него это просто функция. А в языках программирования С и С++ любая функция вызывается только синхронно, т. е. функция, вызвавшая другую функцию, ждет завершения этой функции. Если не использовать квалификатор volatile, то компилятор может оптимизировать код и в одном потоке хранить значение переменной в регистре, а в другом потоке — в оперативной памяти. В результате параллельно работающие потоки будут обращаться к разным переменным. Листинг 3.3. Завершение потока функцией TerminateThread |
||
#include <windows.h> volatile UINT count; void thread() int main() hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, NULL, for (;;) // закрываем дескриптор потока return 0; |
||
|
||
3 |