Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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
1-89371
The X
2003-10-15 18:32
2003.10.27
Корректное масштабирование окон при изменении разрешения


1-89209
REP
2003-10-15 12:05
2003.10.27
ImageList и картинки 256 цветов


11-89192
vosogop
2003-01-31 17:00
2003.10.27
TKOLTCPClient


1-89343
Виталя
2003-10-16 13:27
2003.10.27
Всплывающая подсказка для кнопки


7-89598
uno crezo
2003-08-13 03:58
2003.10.27
регистр и данные dialup-соединения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский