c/C++で書かれたシリアルCOMポートからデータを読み取るReadPortという関数が含まれているDLLがあります。この関数は_beginthreadexを使用する別のWINAPI関数からの余分なスレッド内で呼び出されます。 COMポートに読み込むデータがあると、ワーカースレッドはデータを返し、正常終了し、呼び出し側スレッドはワーカのスレッドハンドルを閉じ、dllはうまく動作します。COMポートの読み取り - タイムアウトが発生した後でもスレッドは生き残っています
ただし、COMポートでデータが保留されていない状態でReadPortが呼び出された場合、タイムアウトが発生するとWaitForSingleObjectはWAIT_TIMEOUTを返しますが、ワーカースレッドは終了しません。その結果、毎回約1 MBの仮想メモリが増え、物理メモリがKBを増やし、DLLを呼び出すアプリケーションが不安定になります。私もTerminateThread()を使用するtryiedしかし、私は同じ結果を得た。
私は十分な開発経験を持っていますが、私は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
は、私は以下の私のコードの一部を投稿してください。
ちょうど文章的なコメント:コードを読むのは難しいです。この質問とは別にリファクタリングすることをお勧めします。これは、共通の引数値を持つ関数を呼び出したり、共通の変数を同じ共通の値に設定したりするセクションに対しては、関数を呼び出して変数を1回だけ設定することです。 –
ありがとうございます。私はあなたが正しいと思いますが、まずこのコードを動作させようとしました。これがうまくいくなら、多分私はそれが書かれたスタイルをいくつか改良するつもりです。しかし、私はいくつかの人々のために、おそらくこれは迷惑なことを理解することができます。とにかくありがとう。 – Sna
これは構造的な問題です。本当にこのコードを再実行する必要があります。重複したI/Oを調べます。あるいは、この種のコードを借りたり盗んだりしてください。 –