У меня есть DLL, которая включает в себя функцию ReadPort, которая читает данные из последовательного COM-порта, написанного на c / c ++. Эта функция вызывается в дополнительном потоке из другой функции WINAPI, используя _beginthreadex. Когда COM-порт имеет данные для чтения, рабочий поток возвращает данные, обычно завершается, вызывающий поток закрывает дескриптор рабочего потока, и DLL работает нормально.
Однако, если ReadPort вызывается без данных, ожидающих на COM-порте, то по истечении времени ожидания WaitForSingleObject возвращает WAIT_TIMEOUT, но рабочий поток никогда не заканчивается. В результате виртуальная память увеличивается примерно на 1 МБ каждый раз, физическая память увеличивается на несколько КБ, и приложение, которое вызывает dll, становится нестабильным. Я также попытался использовать TerminateThread (), но получил те же результаты.
Я должен признать, что, хотя у меня достаточно опыта разработки, я не знаком с c / c ++. Я провел много исследований до публикации, но, к сожалению, мне не удалось решить мою проблему.
Кто-нибудь знает, как я могу решить эту проблему? Однако я действительно хочу придерживаться такого решения. Кроме того, я хочу упомянуть, что я думаю, что не могу использовать какие-либо глобальные переменные для использования каких-то дополнительных событий, потому что функции каждой библиотеки DLL могут вызываться много раз для каждого COM-порта.
Я публикую некоторые части своего кода ниже:
Рабочая тема:
unsigned int __stdcall ReadPort(void* readstr){
DWORD dwError; int rres;DWORD dwCommModemStatus, dwBytesTransferred;
int ret;
char szBuff[64] = "";
ReadParams* params = (ReadParams*)readstr;
ret = SetCommMask(params->param2, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);
if (ret == 0)
{
_endthreadex(0);
return -1;
}
ret = WaitCommEvent(params->param2, &dwCommModemStatus, 0);
if (ret == 0)
{
_endthreadex(0);
return -2;
}
ret = SetCommMask(params->param2, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD| EV_RING);
if (ret == 0)
{
_endthreadex(0);
return -3;
}
if (dwCommModemStatus & EV_RXCHAR||dwCommModemStatus & EV_RLSD)
{
rres = ReadFile(params->param2, szBuff, 64, &dwBytesTransferred,NULL);
if (rres == 0)
{
switch (dwError = GetLastError())
{
case ERROR_HANDLE_EOF:
_endthreadex(0);
return -4;
}
_endthreadex(0);
return -5;
}
else
{
strcpy(params->param1,szBuff);
_endthreadex(0);
return 0;
}
}
else
{
_endthreadex(0);
return 0;
}
_endthreadex(0);
return 0;}
Вызывающая нить:
int WINAPI StartReadThread(HANDLE porthandle, HWND windowhandle){
HANDLE hThread;
unsigned threadID;
ReadParams readstr;
DWORD ret, ret2;
readstr.param2 = porthandle;
hThread = (HANDLE)_beginthreadex( NULL, 0, ReadPort, &readstr, 0, &threadID );
ret = WaitForSingleObject(hThread, 500);
if (ret == WAIT_OBJECT_0)
{
CloseHandle(hThread);
if (readstr.param1 != NULL)
// Send message to GUI
return 0;
}
else if (ret == WAIT_TIMEOUT)
{
ret2 = CloseHandle(hThread);
return -1;
}
else
{
ret2 = CloseHandle(hThread);
if (ret2 == 0)
return -2;
}}
Заранее спасибо,
Sna.