Сообщение Re[4]: Как правильно приостановить поток? от 31.01.2017 7:03
Изменено 31.01.2017 7:04 RussianFellow
Но это был пример использования событий при помощи MFC. А как без MFC?
На www.firststeps.ru я нашёл пример:
HANDLE CreateEvent
(
LPSECURITY_ATTRIBUTES lpEventAttributes, // атрибут защиты
BOOL bManualReset, // тип сброса TRUE - ручной
BOOL bInitialState, // начальное состояние TRUE - сигнальное
LPCTSTR lpName // имя обьекта
);
Если функция успешна, то вернется дескриптор события. В том случае, если с таким именем событие уже создано, то вернется дескриптор уже созданного события, а GetLastError() вернет код ERROR_ALREADY_EXISTS. Но функция может вернуть и NULL, если объект события создать не удалось совсем. Функция SetEvent() меняет состояние на сигнальное (есть событие).
BOOL SetEvent
(
HANDLE hEvent // дескриптор события
);
В случае успеха вернет ненулевое значение. А функция ResetEvent() меняет состояние на невыделенное (нет события):
BOOL ResetEvent
(
HANDLE hEvent // дескриптор события
);
Пример смотрим.
// TestEvent.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"
HANDLE event;
void Test1(void *);
void Test2(void *);
void Test3(void *);
void main()
{
event=CreateEvent(NULL,TRUE,FALSE,"FirstStep");
if (_beginthread(Test1,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test2,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test3,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (event!=NULL){
Sleep(1000);
SetEvent(event);
Sleep(1000);
ResetEvent(event);
CloseHandle(event);
} else {
cout << "error create event" << endl;
}
}
void Test1(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0) {
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 1 TIMEOUT" << endl;
}
cout << "Event Test 1 " << endl;
_endthread();
}
void Test2(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0){
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 2 TIMEOUT" << endl;
}
cout << "Event Test 2 " << endl;
_endthread();
}
void Test3(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0){
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 3 TIMEOUT" << endl;
}
cout << "Event Test 3 " << endl;
_endthread();
}
Создает объект Event, запускает три потока. Каждый поток ждет когда объект синхронизации перейдет в сигнальное состояние. После некоторой задержки устанавливаем его в сигнальное состояние SetEvent(), выжидаем некоторое время, чтобы потоки среагировали и сбрасываем ResetEvent(). Обратите внимание, что в данном случае в отличии от всех других объектов синхронизации потоков может быть любое количество.
То есть я задал flag = 2 для приостановки работы потока, а в потоковой функции я написал
if (*threadflag==2)
// если поток был приостановлен
{
DWORD dwWairResult;
while (dwWaitResult!=WAIT_OBJECT_0)
// ждём, пока не появится событие (по которому надо или продолжить работу потока, или выйти из него)
{
dwWaitResult = WaitForSIngleObject(event,1);
}
if (*threadflag==0)
{
FreeMemory(); // освобождение ресурсов
return; // выход из функции потока
}
// если *threadflag==1 , то продолжаем работу потока
}
то правильно ли я сделал?
Но это был пример использования событий при помощи MFC. А как без MFC?
На www.firststeps.ru я нашёл пример:
HANDLE CreateEvent
(
LPSECURITY_ATTRIBUTES lpEventAttributes, // атрибут защиты
BOOL bManualReset, // тип сброса TRUE - ручной
BOOL bInitialState, // начальное состояние TRUE - сигнальное
LPCTSTR lpName // имя обьекта
);
Если функция успешна, то вернется дескриптор события. В том случае, если с таким именем событие уже создано, то вернется дескриптор уже созданного события, а GetLastError() вернет код ERROR_ALREADY_EXISTS. Но функция может вернуть и NULL, если объект события создать не удалось совсем. Функция SetEvent() меняет состояние на сигнальное (есть событие).
BOOL SetEvent
(
HANDLE hEvent // дескриптор события
);
В случае успеха вернет ненулевое значение. А функция ResetEvent() меняет состояние на невыделенное (нет события):
BOOL ResetEvent
(
HANDLE hEvent // дескриптор события
);
Пример смотрим.
// TestEvent.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"
HANDLE event;
void Test1(void *);
void Test2(void *);
void Test3(void *);
void main()
{
event=CreateEvent(NULL,TRUE,FALSE,"FirstStep");
if (_beginthread(Test1,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test2,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test3,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (event!=NULL){
Sleep(1000);
SetEvent(event);
Sleep(1000);
ResetEvent(event);
CloseHandle(event);
} else {
cout << "error create event" << endl;
}
}
void Test1(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0) {
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 1 TIMEOUT" << endl;
}
cout << "Event Test 1 " << endl;
_endthread();
}
void Test2(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0){
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 2 TIMEOUT" << endl;
}
cout << "Event Test 2 " << endl;
_endthread();
}
void Test3(void *)
{
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0){
dwWaitResult = WaitForSingleObject(event,1);
cout << "Test 3 TIMEOUT" << endl;
}
cout << "Event Test 3 " << endl;
_endthread();
}
Создает объект Event, запускает три потока. Каждый поток ждет когда объект синхронизации перейдет в сигнальное состояние. После некоторой задержки устанавливаем его в сигнальное состояние SetEvent(), выжидаем некоторое время, чтобы потоки среагировали и сбрасываем ResetEvent(). Обратите внимание, что в данном случае в отличии от всех других объектов синхронизации потоков может быть любое количество.
То есть я задал flag = 2 для приостановки работы потока, а в потоковой функции я написал
if (*threadflag==2)
// если поток был приостановлен
{
DWORD dwWairResult;
while (dwWaitResult!=WAIT_OBJECT_0)
// ждём, пока не появится событие (по которому надо или продолжить работу потока, или выйти из него)
{
dwWaitResult = WaitForSIngleObject(event,1);
}
if (*threadflag==0)
{
FreeMemory(); // освобождение ресурсов
return; // выход из функции потока
}
// если *threadflag==1 , то продолжаем работу потока
}
то правильно ли я сделал?