DWORD WINAPI ThreadReadProc (LPVOID lpParam)
{
static BYTE buf_in[12] = { 0 };
while( WaitForSingleObject( mExitReadThreadEvent, 100 ) == WAIT_TIMEOUT )
{
if (!ReadFile(ComHANDLE,buf_in,12,&bc,NULL))
MessageBox (hMainWnd,"Невозможно считать информацию с порта","Ошибка",MB_ICONHAND);
else
MessageBox (NULL,TEXT("......"),"Получены данные",MB_OK);
}
}
DWORD WINAPI ThreadWriteProc (LPVOID lpParam)
{ // поток для отправки информации на устройство... 1 раз в 15 секунд должен отрабатывать
static BYTE nSendData[7] = { 0 };
DWORD numbytes;
И лучше не использовать MessageBox из "рабочих" потоков для идентификации
ошибки, логичнее было бы послать сообщение основному GUI потоку через PostThreadMessage
или PostMessage.
Есть небольшая программка, которая постоянно опрашивает устройство через COM-порт. Для этого сделано 2 потока:
— первый постоянно шлет запросы на устройство (1 раз в 15 секунд), для этого там создан таймер.
— второй постоянно считывает информацию с COM-порта: также через таймер 1 раз в 100мс...
Столкнулся с такой проблемой: почему-то если создавать оба потока, то происходит такой глюк: таймер, в котором происходит отправка сообщения на устройство обрабаывается всего 1 раз, доходит до функции ReadFile, и дальше просто вылетает из потока.
Такая же картина происходит и во время отправки данных на порт, при первом вызове WriteFile вылетает из потока!
Если же создавать только один поток для записи информации в устройство, то таймер работает как часы, все постоянно отправляет...
while (GetMessage(&mess2,NULL,0,0))
DispatchMessage(&mess2);
}
BYTE buf_in[12];
void CALLBACK ThreadReadTimerProc(HWND,UINT,UINT,DWORD)
{
if ((ComHANDLE!=NULL)
if (!ReadFile(ComHANDLE,buf_in,12,&bc,NULL))
MessageBox (hMainWnd,"Невозможно считать информацию с порта","Ошибка",MB_ICONHAND);
else
MessageBox (NULL,TEXT("......"),"Получены данные",MB_OK);
return;
}
DWORD WINAPI ThreadWriteProc (LPVOID lpParam)
{ // поток для отправки информации на устройство... 1 раз в 15 секунд должен отрабатывать
MSG message;
SetTimer (NULL,0,15000, ThreadWriteTimerProc);
while (GetMessage(&message,NULL,0,0))
DispatchMessage(&message);
return 0;
}
void CALLBACK ThreadWriteTimerProc(HWND,UINT,UINT,DWORD)
{ // каждые 15 секунд необходимо отправлять информацию на устройства
static BYTE nSendData[7];
DWORD numbytes;
if (!ComHANDLE)
return;
else
{
for (int i = 1; i <= 32/*0x5*/; i++)
{
nSendData[3] = i;
// подсчет контрольной суммы
nSendData[5] = nSendData[1] + nSendData[4] + nSendData[2] + nSendData[3];
nSendData[5] = 0 — nSendData[5];
bool bRez = WriteFile(ComHANDLE,nSendData,7,&numbytes,NULL);
if (! bRez)
MessageBox (NULL, "Невозможно отправить данные", szCOM, MB_OK);
else
{
Sleep(450);
continue;
}
}
}
return;
}
03.04.07 11:08: Перенесено модератором из 'C/C++' — Odi$$ey
Спасибо за помощь, но не помогло!!! А может такая гадость происходит из-за того, что оба потока пытаются читать и/или писать в один и тот же порт?! Просто если я в обоих потоках ставлю или только функцию чтения или только функцию записи то все отлично работает!!!
Если да, то как можно синхронизовать работу потоков?! Нужно чтобы один постоянно считывал, другой периодически туда информацию слал!!!
Заранее спасибо!!!!
Re[3]: Глюки при работе с потоком
От:
Аноним
Дата:
05.04.07 13:28
Оценка:
_>Если да, то как можно синхронизовать работу потоков?! Нужно чтобы один постоянно считывал, другой периодически туда информацию слал!!!
Здравствуйте, Аноним, Вы писали:
_>>Если да, то как можно синхронизовать работу потоков?! Нужно чтобы один постоянно считывал, другой периодически туда информацию слал!!!
А>CreateMutex() А>WaitForSingleObject(), ReleaseMutex().
Чего за устройство-то?
Два потока ненадо. Достаточно одного! В нём открываешь порт и организуешь очередь по циклу. Итерация = 100мс, и раз в 1500 итераций пишешь в COM. Таймер тож ненадо, сделай Mutex в главном потоке и отдай копию (КОПИЮ DuplicateHandle) handle'а потоку своему. Потом жди этот Mutex по 100мс, если WAIT_TIMEOUT то читаешь или пишеш с COM порта, если WAIT_OBJECT_0, то выходишь из очереди и из потока и закрываешь handle этого mutex'а да и порта.
Вообще, чем больше потоков, тем больше гимора ты себе наживаешь.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Здравствуйте, stepanov_i, Вы писали:
_>Здравствуйте, VladKurmaz, Вы писали:
_>Спасибо за помощь, но не помогло!!! А может такая гадость происходит из-за того, что оба потока пытаются читать и/или писать в один и тот же порт?! Просто если я в обоих потоках ставлю или только функцию чтения или только функцию записи то все отлично работает!!! _>Если да, то как можно синхронизовать работу потоков?! Нужно чтобы один постоянно считывал, другой периодически туда информацию слал!!!
_>Заранее спасибо!!!!
Приведите пожалуйста код создания файла com-порта.
Скорее всего проблема именно в этом.
В MSDN каких-либо играничений по данному вопросу я не вижу
Communications Resources
The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O. For more information about communications, see Communications.
Вопрос следующий: приведите пожалуйста краткую формулировку
прикладной задачи, которую Вы пытаетесь решать.
Потому что бесконтрольное и перекрывающиеся чтение и запись как-то
трудно объяснить логически
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT>Здравствуйте, ZAMUNDA, Вы писали:
ZAM>>сделай Mutex в главном потоке и отдай копию (КОПИЮ DuplicateHandle) handle'а потоку своему.
LT>Почему обязательно копию? Поток-то свой.
Чтоб случайно его не закрыть, когда его в потоке другом ждут. Ибо про WaitForSingleObject сказано:
If this handle is closed while the wait is still pending, the function's behavior is undefined.
А если закроешь дубль Mutex'а, то просто будет Auto-Release.
Короче, конечно это не обязательно, но только для тех, кто любит гИмор и бубны.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков