Страница 1 из 2
Поток – отдельная ветвь выполнения программы. Имеет свой стек и работает независимо от других потоков приложения.
Создание простейшего потока AfxBeginThread(ProcName,param,priority) ProcName – имя функции, которая будет выполнятся в новом потоке param – указатель типа LPVOID или void* на аргумент ProcName priority – константа, определяющая приоритет нового потока по отношению к основному
Может принимать одно из следующих значений:
THREAD_PRIORITY_ABOVE_NORMAL // на один пункт ниже нормального THREAD_PRIORITY_BELOW_NORMAL //на один пункт выше нормального THREAD_PRIORITY_HIGHEST //на два пункта выше нормального THREAD_PRIORITY_IDLE //базовый приоритет равный 1 THREAD_PRIORITY_LOWEST //на два пункта ниже нормального THREAD_PRIORITY_NORMAL //нормальный приоритет THREAD_PRIORITY_TIME_CRITICAL //приоритет равный 15 Приоритет потока определяет, как часто по отношению к другим выполняющимся потокам система будет передавать управление данному потоку
UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from Thread” ,MB_OK); return 0; }
SomeFunc() { AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока } Синхронизация работы потоков.
1. Глобальная переменная
bool bThreadstop; //контрольная переменная
UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); while(!bThreadstop) { //Выполнение опреаций }
::MessageBox((HWND)param, ”Thread ended”,”Message from thread”,MB_OK); return 0; }
SomeFunc() { bThreadstop=false; AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока }
StopThread() { bThreadstop=true; //остановка потока } 2. Взаимодействие с помощью сообщений
const WM_THREADENDED = WM_USER+1; //Это надо добавить в катры сообщений
afx_msg LONG OnThreadEnded(WPARAM wParam,LPARAM lParam);
ON_MESSAGE(WM_THREADENDDED,OnThreadEnded)
bool bThreadstop; //контрольная переменная
UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); while(!bThreadstop) { //Выполнение опреаций }
::PostMessage((HWND)param,WM_THREADENDED,(WPARAM)param,0); //Сообщение return 0; }
SomeFunc() { bThreadstop=false; AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока }
StopThread() { bThreadstop=true; //остановка потока }
LONG OnThreadEnded(WPARAM wParam, LPARAM lParam) { ::MessageBox((HWND)wParam,”Thread Ended”,”Message from thread”, MB_OK); }
//Данный пример закрывает главное окно после выполнения потоковой функции 3. Взаимодействие с помощью объектов событий
Объект событий CEvent может находится в одном из двух состояний – сигнализирует или молчит. Потоки отслеживают момент, когда объект события начинает сигнализировать, и начинаю выполнение операций.
CEvent ThreadStart; //объект автоматически устанавливается в состояние молчания
ThreadStart.SetEvent(); //установка состояния сигнализации Отслеживание состояния объекта осуществляется с помощью функции WinAPI WaitForSingleObject();
:: WaitForSingleObject(ThreadStart.m_hObject,INFINITE); - первый параметр – дескриптор отслеживаемого события. - второй параметр – время отслеживания. INFINITE – бесконечно.
В момент установки события WaitForSingleObject() вернет управление потоку. В момент сброса события поток должен прекратить свою работу. Для этого надо организовать постоянный опрос состояния события.
Это можно сделать следующим способом:
::WaitForSingleObject(ThreadStart.m_hObject,0); Время 0 говорит о том, что надо опросить событие. Если результат вызова этой функции равен WAIT_OBJECT_0, то объект в остоянии сигнализации. В других случаях – молчит.
CEvent ThreadStart; //Объект начала работы потока CEvent ThreadEnd; //Объект окончания работы потока
UINT ThreadProc(LPVOID param) //Создание потоковой функции { :: WaitForSingleObject(ThreadStart.m_hObject,INFINITE); //ожидание запуска потока ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); bool Running=true; int result; while(Running) { //Выполнение опреаций
result=:: WaitForSingleObject(ThreadEnd.m_hObject,0); //проверка завершения if(result==WAIT_OBJECT_0) Running=false; }
::PostMessage((HWND)param,WM_CLOSE,0,0); //Сообщение
return 0; }
Start() //запуск потока { ThreadStart.SetEvent(); }
End() //завершение потока { ThreadEnd.SetEvent(); } Поток нужно создавать независимо от состояния событий.
|