Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Янг Майкл Дж. -> "Visual С++ 6. Полное руководство: В 2 т.(том2)" -> 115

Visual С++ 6. Полное руководство: В 2 т.(том2) - Янг Майкл Дж.

Янг Майкл Дж. Visual С++ 6. Полное руководство: В 2 т.(том2) — Бином, 2006. — 530 c.
Скачать (прямая ссылка): vicualcc2006t2.djvu
Предыдущая << 1 .. 109 110 111 112 113 114 < 115 > 116 117 118 119 120 121 .. 173 >> Следующая

Если параметр dwCreateFlags равен 0 (стандартное значение), то новый поток начинает выполняться немедленно. Если же присвоено значение create_suspended, то он не запустится до вызова функции CWinthread: :ResumeThread, описанной, ниже. Параметрам nStack и IpSecurityAttrs почти всегда присваиваются стандартные значения, определяющие размер стека для потока и атрибуты защиты.
Следующий фрагмент программы запускает новый поток, выполняющий функцию ThreadFunction (и вызываемые ею функции).
UINT ThreadFunction (LPVOID pParam) {
// операторы и вызовы функций, которые должны быть // выполнены новым потоком ...
return 0; // окончание потока и передача кода возврата 0
}
// ...
void SomeFunction (void) (
// . . .
int Code = 1; CWinThread *PWinThread;
PWinThread = AfxBeginThread (ThreadFunction, &Code); II . . .
\
Прекращение выполнения потока
Новый поток можно завершить одним из двух способов. Первый: можно просто возвратиться из потока в функцию потока (функция ThreadFunction в примере выше), передавая код возврата. Это наиболее правильный способ завершения потока. Стек, используемый потоком, освобождается, и все автоматические данные, созданные потоком, удаляются, т.е. вызываются деструкторы для автоматических объектов.
Второй способ: поток может вызвать MFC-функцию Af xEndThread, передавая ей нужный код возврата:
void AfxEndThread (UINT nExitCode);
Вызов функции AfxEndThread - удобный способ немедленно завершить пото-к из вложенной функции (вместо возврата в исходную функцию потока). При этом стек потока освобождается, но деструкторы для автоматических объектов не вызываются.
Обратите внимание: оба способа завершения потока выполняются самим потоком. При необходимости завершить поток из другого потока рекомендуется передать из последнего сигнал в завершаемый поток, по которому он сам себя завершает. Ниже показаны различные способы установки связей между потоками. (В документации рекомендуется для прекращения другого потока вызывать функции Win32 API : .-TerminateThread.)
Управление потоком
Функция AfxBeginThread возвращает указатель на объект класса cwinThread, который управляет новым потоком. Для временной приостановки выполнения потока вызывается функция SuspendThread класса CWinThread.
PWinThread->SuspendThread () ;
В приведенном ниже примере предполагается, что PWinThread содержит указатель типа класса CWinThread, возвращаемый функцией AfxBeginThread.
Для повторного запуска потока можно вызвать функцию CWinThread: :Resu-meThread:
PWinThread->ResumeThread ();
Функция ResumeThread также вызывается для запуска потока, созданного в приостановленном состоянии значением create_suspend параметра dwCreateFlags функции AfxBeginThread.
Приоритет потока, изначально заданный в вызове функции AfxBeginThread, МОЖНО изменить, вызывая функцию CWinThread: : SetThreadPriority. Например, следующая строка увеличивает приоритет.
PWinThread->SetThreadPriority (THREAD_PRIORITY_ABOVE_NORMAL);
Текущее значение приоритета потока можно получить, вызывая функцию CWinThread::GetThreadPriority.
Функция Win32 API ::GetExitCodeThread вызывается, чтобы определить, продолжается ли выполнение потока. Ели выполнение завершено, позволяет получить код возврата (т.е. значение, возвращенное из функции потока пли переданное функции Af xEndThread). В первом параметре функции потока : .-GetExitCodeThread необходимо задать дескриптор Windows, который хранится в переменной m_hThread класса CWinThread.
DWORD ExitCode;
::GetExitCodeThread
(PWinThread->m_hThread, // дескриптор Windows для потока;
SExitCode); // адрес переменной DWORD для
// получения кода возврата
if ExitCode == STILL_ACTIVE)
// поток продолжает выполнение... else
// поток завершен и функция ExitCode содержит код возврата
Функция :: GetExitCodeThread присваивает значение переменной типа DWORD, адрес которой передается во втором параметре. Если поток продолжает выполнение, то переменной присваивается значение STILLACTIVE. Если поток завершился — присваивается значение кода возврата. По этой причине нельзя возвращать специальное значение STILL_ACTIVE, равное 0x00000103L.
При управлении потоками способами, рассмотренными в этом разделе, возникает следующая проблема. После завершения потока объект класса CWinThread, поддерживаемый функцией Af xEndThread, автоматически удаляется. При попытке доступа к объекту класса CWinThread после выхода из потока программа сгенерирует ошибку защиты. Однако чтобы определить, завершен ли поток, необходимо получить доступ к переменной m_HThread класса CWinThread. Решение этой проблемы состоит в предотвращении автоматического удаления объекта класса CWinThread при завершении потока. Для этого присвойте значение FALSE переменной mbAutoDelete класса CWinThread, как в следующем примере.
PWinThread = AfxBeginThread (ThreadFunction, SCode, '
THREAD_PRIORITY_ NORMAL, 0,
CREATE_SUSPENDED) ; PWinThread->m_bAutoDeiete = FALSE; PWinThread->ResumeThread () ;
Поток запускается в1 Состоянии ожидания, чтобы перед выходом из потока установить значение переменной m_bAutoDelete, равное false. Если переменной m_bAutoDelete присвоено значение false, объект класса CWinThread будет существовать даже после выхода из потока, а программа сможет вызвать функцию : :GetExitCodeThread, чтобы определить, выполнился ли поток, и получить код его выхода. Если поток выполнен, то вызов функций класса CWinThread и функции SuspendThread на работе программы не отразится, но последняя функция не будет генерировать ошибку зашиты! После окончания работы с объектом потока его можно удалить явно.
Предыдущая << 1 .. 109 110 111 112 113 114 < 115 > 116 117 118 119 120 121 .. 173 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100