2016-06-28 9 views
1

私はRS232を介してコンピュータBにコンピュータAからデータを送信することができますMFCプログラムを維持しています。データをスムーズに送信することがありますが、時にはそれが永久にハングすることもあります。 comポートに同じデータを順番に送信する2つのスレッドがあります。最初のスレッドはデータを正常に送信しますが、2番目のスレッドはコード "WriteFile"でハングします。コンピュータA上の第二のスレッドが「WriteFile関数」でハングアップしたとき、私は最終的にデータを参照してくださいコンピュータ上の「WriteFile関数」で「1」は、コンピュータBから戻ってコンピュータAに続いてぶら下げ停止ぶら下げ、およびコンピュータBのようないくつかの無意味なデータを送信しますコンピュータAの2番目のスレッドから送信されます。「WriteFile関数は、」永遠にハング、しかし

ここにはRS232 log from computer B があります。

画像は、コンピュータA上の2つのスレッドが自分のテストを開始し、各スレッドが自分のテストを完了し、ほぼ同時に、コンピュータBにTEST_DONEを送信バックコンピュータBにメッセージを送信することを示しています。しかし、コンピュータBは、コンピュータAの最初のスレッドによって送信されたTEST_DONEしか表示しません(この時点で2番目のスレッドはWriteFileでハングしています)。コンピュータBからコンピュータAに手動で「1」を送信します。

コンピュータAからコンピュータBへのメッセージCMDの長さは255

BOOL SerialPort::AutoHandlerRES(unsigned char* cmd){ 
while(wait_transfer.IsLocked()) 
    Sleep(1000); 
wait_transfer.Lock(); 
CString out; 
BOOL RetB; 
UCHAR EndChar[2]={0x0D,0x0A}; 
out=CString(cmd); 
DWORD num = out.GetLength()+2; 
cmd[num-2]=EndChar[0]; 
cmd[num-1]=EndChar[1]; 
RetB=WriteFile(this->m_hCom, cmd, num, &num, NULL); 
Sleep(1000); 
wait_transfer.Unlock(); 
return RetB;} 

である私の質問は、「WriteFile関数」でハングスレッドBの原因となる可能原因である可能性があります何ですか?スレッドAでぶら下がりが発生しないのはなぜですか?ありがとうございました!

+0

それはおそらくあなたの問題とは無関係なのですが、あなたは間違ったロックを使用しています。 '.Lock()'のポイントは、ロックが開いていなければ待つことです。自分で待つ必要はありません。 2回目の睡眠も疑わしい。 – ElderBug

+0

申し訳ありませんが、私は関数をうまく説明しませんでした。この関数は多くのスレッドによって呼び出され、すべてのスレッドは同じRS232 COMポートハンドルを使用します。だから私はスレッドが一度にWriteFileを使用することを確認するためにロックを使用します。 – ohnotme

+0

それは私の言い方を変えない:間違って使っている。 while()もSleep()もないはずです。 – ElderBug

答えて

1

the MSDN page about serial communicationsから:1つのスレッドが完了するために、そのI/O操作を待ってブロックされている場合、元の操作が完了するまで、その後通信APIを呼び出す 他のすべてのスレッドが をブロックされます

。 1つの のスレッドが戻るためのReadFile関数を待っていた場合例えば、WriteFile関数を発行し、他の のスレッドがブロックされます。

ブロックReadFileが発行され、WriteFileが完了しない可能性があります。あなたの場合は、スレッド間の競合状態になります。書き込みは通常、読み取りが呼び出される前に完了しますが、必ずしもそうではありません。

これを防ぐ最良の方法は、ReadFileを不注意に呼び出すのではなく、書き込みと同じロックでラップし、読み取り前にCOMM COMMイベントを受信することです。そのための未処理のWin32呼び出しはSetCommMaskWaitCommEventです。 ClearCommErrorを使用すると、受信したデータの量が受信イベントによって通知されないため、読み取るバイト数を検出できます。

また、同時IOを許可するようにオーバーラップIOを使用することができます。私はそれがきれいだと思うが、それは簡単ではない。

+0

RS232データを無期限に読み込むのではなく、COMMイベントをチェックして受信RS232データをチェックするようにコードを修正する必要があります。どうもありがとうございました! – ohnotme

関連する問題