マルチスレッドに挑戦したい

<プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース...

rinkun さんからの 回答

  • 2008/05/31 18:45
  • 回答No.1
rinkun

ベストアンサー率 44% (706/1571)

まず「永遠と」は「延々と」のつもりかな。

それで仕様を読む限りでは、相手機器も同じプログラムの中でシミュレーションするのでなければマルチスレッドは必要ないように思うけど。
マルチスレッドにしてもあまり書きやすくはないんじゃないかな。

仕様の書き方を変えると
0.ダイヤログを表示して「受信表示」ボタンを待つ
1.ダイアログの「受信開始」ボタンを押されたら
   データ受信開始の合図"0x01"を相手機器に送る
2.受信待ちをする(ここで「受信終了」ボタンも待つ)
3.データを受信する(2と繰り返し)
4.ダイアログの「受信終了」ボタンを押されたら
   データ受信終了の合図"0x02"を相手機器に送る
5.相手機器がデータ送信を止めたことを確認する(?)
6.受信終了
ですね。(5は必要ないかも)

ここで必要なのは、2でCOMポートの受信と「受信終了」ボタンを同時に待つ複数待ちです。これはWIN32APIだとMsgWaitForMultipleObjects等が使えますし、コンソールアプリケーションではselect等も使えますが、MFCでのやり方は覚えてません。
COMポート通信を非同期アクセスにする必要があるかも。
この回答にこう思った!同じようなことあった!感想や体験を書こう!
この回答にはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
関連するQ&A
  • 可変長バイナリを読み込みたい C・C++・C#

    <プログラム環境> Windows XP,VC++6.0,MFC AppWizard(exe),ダイアログベース <目的> COMポートから可変長のバイナリデータを受信する <質問> 受信するバイナリの長さは受信した内容で分かるようになっています。 例えば、 先頭が"0x0b"であれば11個のバイナリが続いて送られてくるという感じです。 この例ように、送られてくる内容("0x0b")を確認して、それに応じて 11個データを読み込む、というプログラムにするには、どのようにしたら良いでしょうか? 今は以下のソースで、バイナリの長さを指定して受信しています。 //////////オーバーラップ構造体の初期化////////// OVERLAPPED old; ZeroMemory( &old, sizeof(old) ); old.Offset = 0; old.OffsetHigh = 0; old.hEvent = hEvent; //////////データ受信//////////////////////////// unsigned char rdBuf[10]; unsigned char* prdBuf; DWORD dwCount; DWORD dwRead; prdBuf = &rdBuf[0]; dwCount = 10; if(ReadFile(hCom,prdBuf,dwCount,&dwRead,&old) == 0){ if(ERROR_IO_PENDING == GetLastError()){ if(WaitForSingleObject(hEvent,INFINITE) == WAIT_OBJECT_0){ if(GetOverlappedResult(hCom,&old,&dwCount,TRUE)){ //"データ受信完了" }}} else //エラー } 宜しければ、ご指摘の程よろしくお願いします。...

  • マルチスレッドにする必要がありますか? C・C++・C#

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース シングルスレッド <目的のプログラム仕様> ・ダイアログのボタンを押すとOnボタン関数に入る ・Onボタン関数で関数1(無限ループ)と関数2(無限ループ)を実行する ・関数1はnDataの内容を更新し続ける(37回/sec) ・関数2はnDataの内容を基に、数秒かかる処理を10秒毎に行う <今の知識で出来るコーディング> void Onボタン関数(){  int nData[10];  関数1(nData);  関数2(nData); } void 関数1(int nData[]){  for(;;) for(int i=0;i<10;i++) nData[i] = 更新データ; } void 関数2(int nData[]){  int nTotal=0;  DWORD dwOldTime = clock();  for(;;){   if(clock() - dwOldTime >10000){//10秒経過で実行    dwOldTime = clock();    for(int i=0;i<10;i++) nTotal += nData[i];//実際は数秒かかる程の処理    nTotal = 0; //初期化   }  } } <問題点> 今の知識で出来るコーディングでは、関数1の無限ループから処理が 他へ移ることは無く、関数2を実行する事が出来ません。 関数2の合計を計算する処理は、実際には数秒かかるので、 関数1で関数2を呼び出すことが出来ません。 (関数1は37回/secでデータ更新しなければならないので) <質問> 目的のプログラム仕様を満たすには、マルチスレッドにしなければ ならないでしょうか? シングルスレッド、マルチスレッド、どちらの方法でも良いので、 どのようにコーディングすれば良いのか教えて下さい。 宜しければ、ご指摘お願い致します。...

  • WriteFileのエラー995は何が原因? C・C++・C#

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース <症状> 以下のコード部分は、これまでエラーは無かったのですが、 他の部分をいろいろといじった結果以下のコードでエラーが出るように なりました。 HANDLE hCom;//COMポートのハンドル OVERLAPPED old;//構造体 unsigned char ucBuf[];//送信する内容 DWORD dwByte;//送信するバイト数 //上記変数は宣言後、正しい値を入れています。 BOOL blRet;//実行結果 if(WriteFile(hCom,ucBuf,dwByte,NULL,&old) == 0){ blRet = GetLastError(); } を実行後、blRetの結果を確認すると995で、 「スレッドが終了したか、またはアプリケーション要求によって、I/O 処理が中止されました。」 が出ました。 <質問> このエラーは何が原因でしょうか? 宜しければご指摘の程よろしくお願いします。...

  • マルチスレッドのスレッド数を増やしたい C・C++・C#

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース <質問概略> CWinThread*を使って無限ループのスレッドを作ったのですが、 無限ループのスレッドをもう一つ作り、同時に実行しようとするとアクセスバイオレーションのエラーでます。 複数スレッドの作り方を教えていただけますと幸いです。 <質問詳細> 現状の正常に実行できるソースの必要最小限を書きます。 <.h> class CMyDlg : public CDialog{ public:   static UINT ThreadFunc( LPVOID pParam );   void Thread(); // スレッドの処理 protected:   CWinThread* m_pThread;//スレッドのアドレス }; <.cpp> void CMyDlg::OnButton(){   m_pThread = AfxBeginThread( ThreadFunc, this );   for(;;) /*無限ループ処理1*/ ; } UINT CMyDlg::ThreadFunc( LPVOID pParam ){   ((CMyDlg*)pParam)->Thread();   return 0; } void CMyDlg::Thread(){   for(;;) /*無限ループ処理2*/ ; } これに、 void CMyDlg::Thread2(){   for(;;) /*無限ループ処理3*/ ; } のようなスレッドを追加したいのですが全然出来ません。 宜しければご指摘お願い致します。...

  • バイナリをテキストファイルに書き込みたい C・C++・C#

    <プログラム環境> Windows XP,VC++6.0,MFC AppWizard(exe),ダイアログベース <目的> COMポートから受信した可変長バイナリデータを1.txtに書き込む。 ※バイナリエディタを使用せずに16進数で読めるように書く <質問> 受信したバイナリデータは「02 80 9a 00 b1 56」なのですが、これをテキストファイルに16進数で書き込むことができません。 どのようにしたら良いでしょうか? 今は以下のソースです。 コメントアウト部分はMessageBox等で表示する処理をしています。 先頭1バイト受信→"06"を受信したのでさらに6バイト受信→6バイト書き込む。という順序です。 以下で実行するとファイルには「 00000」と書き込まれました。何なのか全く分かりません・・。 //////////先頭の1バイトだけ受信する///////////////////////////////////////// DWORD bLError; unsigned char ucLen; DWORD dwCount = 1; DWORD dwRead; if(ReadFile(hCom,&ucLen,dwCount,&dwRead,&old) == 0){ if(ERROR_IO_PENDING == GetLastError()){ bLError = WaitForSingleObject(hEvent,100); if(bLError == WAIT_OBJECT_0){ if(GetOverlappedResult(hCom,&old,&dwCount,TRUE));//データ受信完了 } else if(bLError == WAIT_FAILED);//受信スリープエラー else if(bLError == WAIT_TIMEOUT);//受信タイムアウト } else ;//受信エラー } //////////先頭データの情報から可変長で読み込む////////////////////////////// unsigned char rdBuf[256]; unsigned char* prdBuf; prdBuf = &rdBuf[0]; dwCount = ucLen; if(ReadFile(hCom,prdBuf,dwCount,&dwRead,&old) == 0){ if(ERROR_IO_PENDING == GetLastError()){ bLError = WaitForSingleObject(hEvent,100); if(bLError == WAIT_OBJECT_0){ if(GetOverlappedResult(hCom,&old,&dwCount,TRUE))));//データ受信完了 } else if(bLError == WAIT_FAILED);//受信スリープエラー else if(bLError == WAIT_TIMEOUT);//受信タイムアウト } else ;//受信エラー } //////////データ書き込み///////////////////////////////////////////////////// HANDLE hFile; hFile = CreateFile( ".\\ScanData\\1.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED,NULL ); char Buf[256]; char wBuf[256] = ""; wsprintf(Buf,"%#02x",rdBuf); for(BYTE i=1;i<dwRead;i++){ wsprintf(Buf,"%#02x ",rdBuf[i]); wBuf[i] = Buf[0]; } if(WriteFile( hFile, wBuf,dwRead, &wbyte, &old ) == 0){ if(ERROR_IO_PENDING == GetLastError()){ if(WaitForSingleObject(hEvent,1000)==WAIT_OBJECT_0){ if(GetOverlappedResult(hCom,&old,&wbyte,TRUE)){//データ書き込み完了 }}} else ;//データ書き込みエラー } //////////受信したデータ10バイト分をMessageBoxで表示////////////////////// wsprintf(Buf,"文字 = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",rdBuf[0],rdBuf[1],rdBuf[2],rdBuf[3],rdBuf[4],rdBuf[5],rdBuf[6],rdBuf[7],rdBuf[8],rdBuf[9]); MessageBox(Buf); 宜しければ、ご指摘の程よろしくお願いします。...

ページ先頭へ