Форум: "Система";
Текущий архив: 2003.10.27;
Скачать: [xml.tar.bz2];
ВнизСинхронизация внешних событий с потоком Найти похожие ветки
← →
Nick_Omsk (2003-08-16 09:35) [0]Здравствуйте. Есть проблема. Существует поток, который обрабатывает сообщения, приходящие по IPX-протоколу, т.е. событие получения данных имеет случайный разброс во времени. Я в процедуре получения пакета добавляю пакет в очередь, а в потоке уже его обрабатываю. Все время выдаёт ошибку о неправильном доступе к памяти. Бьюсь с этим уже третью неделю. Подскажите пожалуйста, что нужно сделать?
← →
Evgeny V (2003-08-16 10:35) [1]Защита данных общих для разных потоков может быть осуществлена через например критические секции, смотри
InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection,De leteCriticalSection. Для сигнализации потоку(передачи команд) о том что что-то надо сделать обычно использует Event(SetEvent) и соответственно функции ожидания в потоке WaitForSingleObject,WaitForSingleObjectEx и WaitForMultipleObjects и WaitForMultipleObjectsEx, а также через посылки сообщения потоку PostThreadMessage и получения сообщения WaitMessage,PeekMessage и др.
← →
Nick_Omsk (2003-08-16 11:50) [2]Допустим я послал message с помощью PostThreadMessage. Каким образом я его отловлю в потоке? И остановится ли процедура Execute на время обработки этого сообщения?
← →
Evgeny V (2003-08-16 13:46) [3]Пример на си++ билдер
#define WM_DATASET_CLOSE WM_USER +501
#define WM_DATASET_SQL WM_USER +502
HWND hWnd;
hWnd=NULL;
bool ready=false;// В принципе вместо нее можно использовать
TThread->Terminated, ну да привычка:-)))
void __fastcall MyDataSet::Execute()
{
//---- Place thread code here ----
ready=true;
while(!Terminated)
Dispath();
ready=false;
}
void __fastcall MyDataSet::Dispath(void)
{
//TODO: Add your source code here
int cmd,k;
wMsgFilterMin=WM_DATASET_CLOSE;
wMsgFilterMax=WM_DATASET_CLOSE;
if(!WaitMessage())// здесь execute висит и ждет Message, например что появился пакет
return;// не обрабатываю возможные ошибки
//Проверка нет ли команды на завершение потока
if(PeekMessage(&Msg,hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg))
{
Terminate();
return;
}
wMsgFilterMin=WM_DATASET_SQL;
wMsgFilterMax=WM_DATASET_SQL;
//Проверка других допустимых команд
if(!PeekMessage&Msg,hWnd,wMsgFilterMin,wMsgFilterMax,wRemoveMsg))
return;// нет моих команд - ухожу
cmd=Msg.wParam;
k=cmd;// далее что-то делаю
switch(cmd)
{
case SSQL:
if(!ExecS())
k=-k;
SignalOut(k);
break;
case USQL:
if(!ExecU())
k=-k;
SignalOut(k);
break;
case ISQL:
if(!ExecI())
k=-k;
SignalOut(k);
break;
case DSQL:
if(!ExecD())
k=-k;
SignalOut(k);
break;
}//end switch
}
void __fastcall MyDataSet::SignalOut(int cmd)
{
//TODO: Add your source code here
PostMessage(w,WM_TBLUPD,ID,cmd);
//Шлю в главную форму мессагу, что выполнил команду,ID У меня тут фактически ID потока, cmd - команда которую подтверждаю, если неуспешно выполнил, то cmd отрицательно, ну да по тексту видно. Можешь по своему
}
// Так я из основного окна изменяю данные, к которым имеет доступ поток и поток главного окна
void __fastcall MyDataSet::SetSSQL(AnsiString s)
{
//TODO: Add your source code here
if(!ready)// ready лог. переменная, устанавливается в начале Execute,
return;
EnterCriticalSection(&MyDefLs);
ssql=s;
LeaveCriticalSection(&MyDefLs);
SignalIn(SSQL);// Посылка команды потоку
}
void __fastcall MyDataSet::SignalIn(int cmd)
{
//TODO: Add your source code here
UINT Msg;
if(ready)
{
if((cmd>DSQL) || (cmd<SCLOSE))
cmd=SCLOSE;
if(cmd==SCLOSE)
Msg=WM_DATASET_CLOSE;
else
Msg=WM_DATASET_SQL;
PostThreadMessage(ThreadID,Msg,cmd,0);
}
}
Кстати неплохо бы код поместить было твой, если ошибки будут у тебя продолжаться, проблема может быть еще в чем:-)))
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.10.27;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.012 c