• ベストアンサー

WaitForMultipleObjects関数の待機状態から抜けるにはどうすればいいのですか。

nda23の回答

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

ところで、誰がイベントをシグナル状態にするんですか? 誰も何もしていないような気がします。 普通は受信割り込み処理の中でSetEventします。

cpptext
質問者

補足

えーと、退職した前任者からのひきつぎなので、勉強しながらのプログラミングなのですが、overlappedCommEvent.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); でシリアルからデータが来た場合にイベントが立つんじゃないんでしょうか? 接続先のPCのキーボードをたたいて、データが飛んできて、それに反応する割り込み処理?が必要なのでしょうか。 すみません、勉強しながらなので、いまいちシーケンスの深い理解が得られておりません。

関連するQ&A

  • マルチスレッドプログラミングについて

    マルチスレッドプログラミングについていくつか教えて下さい。 マルチスレッドの基礎がまだ分かってないので初心者でも分かり易いようにお願いします。 1:イベントオブジェクトについて教えて下さい。 「イベントオブジェクト」の概念がよく分かりません。 ○シグナル状態と非シグナル状態とはどういう状態なのでしょうか? ○自動リセットの場合ではどのタイミングで切り替わっているのでしょうか?(下記のソースの場合) ○手動リセットの場合ではどのタイミングで切り替えればよいのでしょうか?(下記のソースの場合) 2:CloseHandle() と ExitThread() について教えて下さい。 ○この2つの関数の役割の違いについて教えて下さい。 「スレッドハンドルを閉じる=スレッドを終了」ではないのでしょうか? また、これらの関数実行時にシグナル状態は気にする必要はありますか?(シグナル状態にしなくてよいのか?) 下記のソースは簡略化のためかなり省略されています。 DWORD WINAPI ThreadProc( DWORD i ) { while( true ) { DWORD r = WaitForMultipleObjects( 2, hEvent, FALSE, INFINITE ); if( r == WAIT_OBJECT_0 ) { // 処理1 } else if( r == WAIT_OBJECT_0 ) { // 処理2 } else { ExitThread( TRUE ); // スレッド終了 } } } void MainProc() { // 自動リセットのイベントオブジェクト作成 for( int i=0; i<2; i++ ) { hEvent[i] = CreateEvent( NULL, FALSE, FALSE, NULL ); } // スレッドを作成 hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, &dwThreadID ); }

  • C++ GUIのメッセージループ。

    初心者です。 よろしくお願いします。 とても重く時間の掛かる処理を色んなサイトを参考にスレッドにしてみたんですけど、書き方が悪いのか、再描写がワンテンポ遅れたり、アプリケーションを複数起動したりするとフリーズしてしまったりします。 原因はメッセージループにあるような気がしてるんですが、この書き方はおかしいですか?? どのサイトから引用したのかわからなくなってしまいました。 気付いたことなどあったら何でもいいので教えて貰えたら嬉しいです!よろしくお願いします!! thread01に重い処理が書かれてます。 int thread_call() {   unsigned int dwThreadId[1];   HANDLE hThread[0] = (HANDLE)_beginthreadex(     NULL,     0,     ( unsigned int (__stdcall*)(void*) )thread01,     NULL,     0,     &dwThreadId[0] );   MSG msg;   DWORD dwRet = WAIT_TIMEOUT;   while ( 1 ) {     dwRet = ::MsgWaitForMultipleObjects( sL, hThread, FALSE, INFINITE, QS_ALLEVENTS );     if ( dwRet == WAIT_OBJECT_0 + sL ) {       if ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {         ::TranslateMessage( &msg );         ::DispatchMessage( &msg );       }     } else if ( dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0 + sL )       break;   }   CloseHandle( hThread[0] );   hThread[0] = NULL; }

  • CloseHandle()

    スレッドを、同じハンドルを利用して作る場合、 途中でハンドルの開放が必要か教えてください。 void thread1(); HANDLE handle; //スレッド作成 handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread1, NULL, 0, &dwID); //作ったスレッドの終了を待つ WaitForMultipleObjects(1, handle, TRUE, INFINITE); //スレッドを作った時のハンドルを閉じる。これ必要? CloseHandle(handle); //同じハンドルを利用して別のスレッドであるthread2を作成 handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread2, NULL, 0, &dwID); この、CloseHandle(handle);は必要ですか?

  • スレッドについて

    スレッドについて勉強中なのですが、簡単なスレッド作り、 スレッドの処理が終わってからメインの処理を行わせたくて 以下のようなプログラムを書いてみました。 そこで、WaitForSingleObjectを使ってスレッドが終了するのを 待ちたいのですが、WaitForSingleObjectではまってしまうようで sprintfのメッセージ(スレッドが止まってしまっている)が 表示されません。 WRITE関数の処理が終われば、、WaitForSingleObjectで処理が 戻ってくると考えているのですが…。 スレッドについてと、間違いについて教えてもらえないでしょうか? 宜しくお願いします。 main { if(!stop) {   File = CreateFile(...); g_hThead = CreateThread(NULL,0,WRITE,(LPVOID)NULL,0,NULL); g_stop = false; }else { g_stop = true; ::WaitForSingleObject(g_hThead, INFINITE); CloseHandle(File); CloseHandle(hThead ); } } void WRITE() { while(!g_stop) { WriteFile(...); } ...処理を行う sprintf("スレッドを終了します。") }

  • マルチスレッドプログラム

    いつもお世話になっております。 今回はマルチスレッドプログラムについてお聞きしたいです。 マルチコアCPUを使ってたとえば下記のようなことをしたいときに for (int i = 0; i < 1000000; i++) { sum += i; } このまま計算するよりもいくつかスレッドを作って、計算量を分散させてから最後に足してやるほうが早いと思いまして、 現在Core2Quadが手元にありましたのでスレッドを4つ作って スレッド1で0から250000まで スレッド2で250001から500000まで スレッド3と4も同様にして実際にやってみたのですが スレッドなしの状態よりも倍くらい時間がかかってしまうようになってしまいました。 計算結果は同じになり、CPU使用率もシングル時が25%、マルチ時が100%になっているので意図したようにはできていると思います。 GetProcessAffinityMaskを使って、各スレッドにひとつづつコアを割り当てても同様でした。 実際に時間が4分の1に近くなると思っていたのですが2倍かかってしまったので不思議です。 どなたか上記のことを思惑通りに動かせそうな方法をご存知の方はご教授願います。 プログラムは全部は無理ですが重要そうなところは下記のとおりです。 スレッド作成部分 {   DWORD dwStart = ::timeGetTime();   _thread_handle[0] = (HANDLE)::_beginthreadex(NULL, 0, thread_first, NULL, CREATE_SUSPENDED, &_thread_first_id);   _thread_handle[1] = (HANDLE)::_beginthreadex(NULL, 0, thread_second, NULL, CREATE_SUSPENDED, &_thread_second_id);   _thread_handle[2] = (HANDLE)::_beginthreadex(NULL, 0, thread_third, NULL, CREATE_SUSPENDED, &_thread_third_id);   _thread_handle[3] = (HANDLE)::_beginthreadex(NULL, 0, thread_forth, NULL, CREATE_SUSPENDED, &_thread_forth_id);   for (int num = 0; num < 4; num++)   {     ::ResumeThread(_thread_handle[num]);   }   ::WaitForMultipleObjects(4, _thread_handle, TRUE, INFINITE);   for (num = 0; num < 4; num++)   {     ::CloseHandle(_thread_handle[num]);   }   DWORD dwEnd = ::timeGetTime(); } 各スレッド部分 { HANDLE hCurrent = ::GetCurrentProcess(); DWORD pamask, samask, patmp = 0; int nRet = ::SetProcessAffinityMask(hCurrent, 0x0001); ::GetProcessAffinityMask(hCurrent, &pamask, &samask); DWORD dwStart = ::timeGetTime(); _result1 = 0; for (int multi = 0; multi < _multi; multi++) {   for (DWORD i = 0; i < 100000/4; i++)   {     _result1 += i;   } } DWORD dwEnd = ::timeGetTime(); time1 = dwEnd - dwStart; ::_endthread(); return 0; } 開発環境は WindowsXP SP3 VisualStudio6.0 ATL/WTLです。

  • バイナリを16進数で表示したい

    VC++6.0,MFC,ダイアログベースでバイナリデータ受信とファイル書き込みのプログラムを作っています。 COMポートからバイナリを10バイト受信し、受信した内容を1.txtに書き込み、1.txtを開いて、受信した内容を確認したいです。 以下のソースで実行すると、1.txtにはFフフフフフフフフフと書かれていました。これを16進数で表示させたり、10進数で表示させるにはどうしたらいいでしょうか? /////////データ受信////////////// 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 //エラー } /////////ファイルに書き込む////////////// HANDLE hFile; hFile = CreateFile( ".\\ScanData\\1.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL ); if(WriteFile( hFile, rdBuf,10, &wbyte, &old ) == 0){ if(ERROR_IO_PENDING == GetLastError()){ if(WaitForSingleObject(hEvent,INFINITE)==WAIT_OBJECT_0){ if(GetOverlappedResult(hCom,&old,&wbyte,TRUE)){ //書き込み完了 }}} else //書き込み失敗 }

  • スレッドの終了を知りたい(WindowsAPI)

    CreateThread()で作成したスレッドの終了を知りたい (具体的には、スレッドが終了するまで待機したい)のですが、 うまくいかず困っています。WindowsAPIに関する本やネットで調べた ところ、WaitForSingleObject()が適用できると考え、 以下のようなプログラムを作成したのですが、 元のスレッドがWaitForSingleObject()のところで 止まると同時に、CreateThread()で作成されたThread_1()も 止まってしまいます。アドバイスいただけますでしょうか。 ----プログラム(該当部分)ここから---- DWORD Thread_1(LPVOID param) {  int i;  char buff[128];  /* iが99のときのみ終了してよい */  while(g_iFlg == 1)  {   for(i = 0; i < 100; i++)   {    Sleep(100);    wsprintf(buff, "%d", i);    SetDlgItemText((HWND)param, IDC_STATIC_1, buff);   }  }  ExitThread(0);  return 0; } BOOL CALLBACK Proc_2(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {  switch(uMsg)  {   case WM_INITDIALOG:    g_iFlg = 1;    g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_1, (LPVOID)hDlg, 0, &g_dwThread);    return TRUE;   case WM_COMMAND:    switch(LOWORD(wParam))    {     case IDC_BUTTON_CANCEL:     case IDCANCEL:      g_iFlg = 0;      WaitForSingleObject(g_hThread, INFINITE);      CloseHandle(g_hThread);      EndDialog(hDlg, 0);      return TRUE;    }  }  return FALSE; } ----プログラム(該当部分)ここまで----

  • 非同期のプロセス間通信(パイプ)で全データ受信する

    こんにちは。 非同期のプロセス間通信(パイプ)で詰まっています。 環境はWindowsで処理系はC++(Win32)です。 スレッドを用意して、 hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; で作成し、OVERLAPPED構造体を // ZeroMemory( &so, sizeof( OVERLAPPED )) ; sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ; として、 const size_t bufsize = 16 ; BYTE     buffer[ uBufSize ] ; DWORD    dwNumberOfBytesRead ; bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ; で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、 switch( ::GetLastError()) {   case ERROR_IO_PENDING :     bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ;     break ; } としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。 シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。 上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、 残りの部分のみしか取得できませんでした。 0123456789ABCDEFabcdefg というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。 すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?

  • ReadFileでエラーが出ます。

    シリアルポートで非同期でバイナリを受信するプログラムを作成しています。 受信部分は以下のソースです。これで実行すると「データ受信エラー」のダイアログが出ます。 GetLastErrorでは998(メモリ ロケーションへのアクセスが無効です。)が得られました。 ネットで調べましたが何が原因かも分かりません・・。 どうかアドバイスお願いします。 HANDLE hEvent; hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); OVERLAPPED old; ZeroMemory( &old, sizeof(old) ); old.Offset = 0; old.OffsetHigh = 0; old.hEvent = hEvent; DWORD dwCount; char* rdBuf; DWORD dwRead; if(!ReadFile(hCom,rdBuf,dwCount,&dwRead,&old)){ if(ERROR_IO_PENDING == GetLastError()){ GetOverlappedResult(hCom,&old,&dwRead,TRUE); } else MessageBox("データ受信エラー","試作1",MB_ICONSTOP); }

  • マルチスレッドプログラミングについて

    こんばんわ。 マルチスレッドプログラミングを行なっています。開発環境はVC++.NET2003でC言語を用いてコンソールアプリケーションを勉強中です。 以下にプログラムを示します。 以下のプログラムは、 (1)ThAとThBが交互に1~10までカウントUP (2)ThBだけが11~20までカウントUP (3)ThAはTh11から、ThBは21からカウントUP というプログラムを記述したつもりなのですが・・・実行開始後は(1)から(3)のように表示できるのですが、それ以降はThAとThBが交互に表示されてしまいます。 (1)から(3)を繰り返す記述の仕方はありますでしょうか? よろしくお願い致します。 HANDLE hEvent[3]; unsigned __stdcall ThB(void *lpx){ int j; int l=1; for(j=1;j<100;j++){ Sleep(100); printf("ThB%d\n",j); if(l%20==0){ SetEvent(hEvent[0]); } l++; } return 0; } unsigned __stdcall ThA(void *lpx){ int k; int j=1; for(k=1;k<100;k++){ Sleep(100); printf("ThA%d\n",k); if(j%10==0){ WaitForSingleObject(hEvent[0],INFINITE); } j++; } SetEvent(hEvent[2]); return 0; } int main(int argc ,char *argv[]){ unsigned int thID[2]; HANDLE hTh[2]; int i; hEvent[0] = CreateEvent(NULL, TRUE, FALSE, "CH0"); hEvent[1] = CreateEvent(NULL, TRUE, FALSE, "CH1"); hEvent[2] = CreateEvent(NULL, TRUE, FALSE, "MAINEVENT"); hTh[0] = (HANDLE)_beginthreadex(NULL, 0, ThA, NULL, 0, &thID[0]); hTh[1] = (HANDLE)_beginthreadex(NULL, 0, ThB, NULL, 0, &thID[1]); WaitForSingleObject(hEvent[2], INFINITE); for(i=0;i<2;i++) CloseHandle(hTh[i]); return 0; }