• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:別スレッドのデータを受信できない)

別スレッドでデータを受信できないときの解決方法

Dodonpa2の回答

  • Dodonpa2
  • ベストアンサー率82% (19/23)
回答No.4

ハードウェア ↓ 受信スレッド・・・無限ループで待機 ↓(PostMessage発行) FormView ↓(供給データを作成) ハードウェア こういうことでいいのでしょうか?未だに全体像がつかめないので 的外れかもしれませんが、受信スレッドで無限ループで待機ってのが いやですね。 ハードウェアからどのようにデータを受け入れているかにもより ますが、CEventの同期オブジェクトとか使って待機してはどうでしょう? 3に関しては、CIlcMyViewにメンバ変数用意しておいて CIlcMyView::OnRcvStsでその変数にコピーすればいいのでは? そういう単純な問題でない? 4.自作DoEvents作るのでしたら、普通新たなスレッド作りますし、 1つのメッセージキューで2つのポンプが存在していたらどういう 動作になるか不明かと思います。(やったことないので) CWinThread::Run()内のDispatchMessageでメッセージを送出後、 FormViewのウィンドウプロシージャでこのDoEventsが実行されたら、 ウィンドウプロシージャは終了せず、その戻値を待っている DispatchMessageが固まりますよね。 もちろん、DoEventsでメッセージは処理していますが、MFCの メッセージポンプはその他にもアイドル処理(CWinThread::OnIdle)が 実行されていたりするので、おかしなことになる可能性は 当然出てくるかと。 FormView側も無限ループではなく、CEventを使ってCEvent::SetEvent() でトリガーしてデータ送り出すというようなことはできないので しょうか?

参考URL:
http://msdn.microsoft.com/ja-jp/library/efk30beh(v=vs.80).aspx
gammodler
質問者

補足

Dodonpa2様 何度もお付き合いくださりありがとうございます。 状況の説明が明確ではありませんでした。以下に箇条書きします: 1.受信スレッド while(monitorDev_FlagExitThread == TRUE){ recvSize = recv(s, buf, sizeof(buf), 0); data = strtol(str, NULL, 16); ::PostMessage(pView->hWnd, WM_USER_RCVSTS, (WPARAM)data, (LPARAM)data); return 0; } 上記のようにsocket接続されたハードウエアからデータをループして取り込んでいます。 recvがBlocking動作をしているのでこのループはハードウエアの更新速度に一致し50msecです。 これは与件としなければなりません。 データ内容は間違いありません。 2.pView側 こちらもデータ作成送出のためにループが組まれています。このループは受信スレッドのそれとはまったく同期していません。 hWnd = GetSafeHwnd(); while (!end){ if (data) data_a作成送出 else data_b作成送出 } このdataが受信スレッドから送られてくると期待しているものです。 3.Viewクラスでの受け手 LRESULT CIlcMyView::OnRcvSts(WPARAM wParam, LPARAM lParam) {  data = wParam; return(0); } このdataはこの関数の中では確かに変化していますが、外側つまり2項のような形では取り出せません。 つまり関数内は受信スレッドに属しているようです。現に2項の主要部分を関数内に記述したところ動作しました。 ただしwhile文の記述は好ましくないようです。 これが解決すべき課題です。 4.非同期性  仮にdataが取り出せ2項記述が可能になったとした場合、二つのループは同期していません。dataを参照しただけでメッセージポンプしてしまうとしたらアンバランスが発生するでしょう。現に2項を関数内に記述したとき、それが原因と伺わせる障害がありました。 どうも基本的なことが分かっていません。もう少しお教え願えれば幸いです。

関連するQ&A

  • Modalダイアログを他のThreadから閉じたい

    VC++6.0のMFCプロジェクトで、Modalダイアログを他のThreadから閉じる処理を行いたいと考えています。 以下のようなことを実行しているのですが、3.で"MyDialog"にメッセージが送信されません。 1.あるFormView上で、他のスレッド("WorkerThread"とします)を起動する。 2.上記FormView上で、Modalダイアログ("DialogTest"とします)を開く。 3."WorkerThread"にて、一定の処理後にSendMessageを実行して、"MyDialog"にメッセージを送り、EndDialog()を実行させる。 /*----- WorkerThread関数内-----*/ //"TestDialog"のハンドルを取得する。 HWND hWnd = ::FindWindowEx(NULL, NULL, _T("#32770"), NULL); if (hWnd) { CWnd* pWnd = FromHandle(hWnd); if (pWnd) { //処理がここに入っていることは確認できます。 pWnd->SendMessage(WM_MESSAGE_CLOSEDIALOG, 0, 0); } } /*-----定義用ヘッダーファイル------*/ const UINT WM_MESSAGE_CLOSEDIALOG =::RegisterWindowMessage(_T("UWM_MESSAGE_CLOSEDIALOG")); /*-----DialogTest.h------*/ //{{AFX_MSG(CWaitingSearchDialog) //}}AFX_MSG afx_msg void OnCloseDialog(WPARAM wParam,LPARAM lParam); DECLARE_MESSAGE_MAP() /*-----DialogTest.cpp------*/ void DialogTest::OnCloseDialog() { EndDialog(IDOK); } BEGIN_MESSAGE_MAP(DialogTest, CDialog) //{{AFX_MSG_MAP(DialogTest) //}}AFX_MSG_MAP ON_REGISTERED_MESSAGE(WM_MESSAGE_CLOSEDIALOG, OnCloseDialog) END_MESSAGE_MAP() 間違いありましたら、ご指摘いただけないでしょうか。よろしくお願いいたします。 (ところで、私が同カテゴリに先日投稿した「"複数プロジェクトをビルドしたとき、DLLに新しく追加したClassのみがリンクエラーになる "」は、自己解決できました。 もしどなたか適当な回答を投稿してもらえれば、その旨を書けます。お暇な方、お願いできないでしょうか)

  • ほかのアプリケーションからのメッセージの取得

    他のアプリケーションからのメッセージの取得方法を教えて下さい。 現在マインスイーパを起動し、そのボタンが押下される順番を記憶するプログラミングを制作しています。 マウスの左クリックに関するメッセージを取得すれば良いと思い、 GetMessage(&msg, hWnd, WM_LBUTTONDOWN, WM_LBUTTONUP);←hWndはマインスイーパのウィンドウハンドル のように書いたんですが、うまくいきませんでした。 調べてみるとGetMessageの第二引数は呼び出し側のスレッドに所属していなくてはならないということで、 この辺が原因なのだろうと思うのですが…。 どなたかご教授ねがいます。 <環境>  Windows Vista Home Premium  Visual C++ Express Edition

  • WINAPIのスレッドについて教えてください

    WINAPIのスレッドについて教えてください スレッドを作成して写真をスライドショウー的に表示しようしていますが、 上手くいきません。 typedef struct _dataparam{ HWND hWnd; HDC hSlidDC; int iFileCount; TCHAR szFile[100][MAX_PATH]; HBITMAP hBitmap[100]; }DataParam; という構造体を作成して、各変数に必要な値を代入した後 BIT_SLIDというメッセージが来た場合Threadを作成。 LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { static DataParam data={0}; case WM_CREATE: data.hWnd=hWnd; ・ ・ case BIT_SLID: slidCheck=TRUE; CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SlidThread, (LPVOID)&data,0,&dwThreadId); return 0; Thread関数内でGetClientRectにより下記のように Windowのサイズを測ろうとしましたが rcには正しいWindowのサイズ格納されていません。 DWORD WINAPI SlidThread(LPVOID vdParam) { DataParam *SlidData; RECT rc={0}; SlidData=(DataParam *)vdParam; GetClientRect(SlidData->hWnd,&rc); ・ ・ ・ hWnd以外のiFileCountやszFile[100][MAX_PATH]の値を調べると 問題なく引き渡しているようなのですが、 rcのleft=0 light=459 top=760 bottom=-2142242063となっていました。 けれどThread関数内で InvalidateRect(SlidData->hWnd,NULL,TRUE); 再描画を行います。 ちなみに下記の自作関数では問題なくWindowサイズを取得しております。 int MySetBitmap(HDC hNormalDC,DataParam *data) { GetClientRect(data->hWnd,&rc); ・ ・ ・ 環境はMicrosoft Visual C++ 2008 Express Editionです それと別件なのですが、デバックでローカルに表示される変数と 表示されない変数がありますがその違いを教えていただければ幸いです。 今回SlidDataは表示されません。 ご教授お願いします。

  • スレッドとメッセージキューに関して

    現在、下記のようなプログラムを作成しています。 内容は、メッセージキューを受信するスレッドを生成するというイメージです。 処理内容は下記のようになります。  (1)メッセージキューの生成  (2)スレッド生成(メッセージキュー受信側)  (3)スレッド停止  (4)メッセージキューの削除 しかし、(3)のスレッド停止を実施しても、(4)のメッセージキューの削除以降にて、msgrcvのエラーが出力されてしまいます。 スレッド停止を行ったことから、TestThreadは動作しなくなり、(4)のメッセージキューの削除にて、エラーともならずに終了することを望んでりますが、上手くいきません。 下記に作成しているプログラムを記載いたします。 正常終了をするには何がいけないのでしょうか? ご教授宜しくお願い致します。 [test.cc] ---------------------------------------------------------------- #include <time.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <stdlib.h> #include <pthread.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> // メソッドポインタ定義 typedef void (*testT); // スレッドID pthread_t threadId; // メッセージキュー識別子 int msqId; // 送受信するメッセージ struct msgbuf{ long int type; char data[BUFSIZ]; }; // テストスレッド void TestThread() { // メッセージ struct msgbuf message; while( 1 ) { printf("### TEST ###\n"); printf("msq start\n"); // 受信 if( msgrcv( msqId, &message, BUFSIZ, 0, 0 ) == -1) { printf("ERR! msgrcv errno[%d]\n", errno); continue; } printf("msq ed\n"); sleep(1); } return; } // メイン int main(int argc, char *argv[]) { // メッセージキュー識別子退避変数 int testMsqid; // スレッド操作リターン値 int status; // スレッドa用のパラメータ pthread_t thread_test; printf("### TEST START ###\n"); // メッセージキューの作成 if( (testMsqid = msgget((key_t)1111, 0666 | IPC_CREAT)) == -1 ) { printf("ERR! CREATE bkMsqId[%d]\n", testMsqid); return 1; } // メッセージキュー識別子を共通変数に設定 msqId = testMsqid; printf("msgget OK\n"); sleep(5); // スレッドを生成 status = pthread_create(&thread_test, NULL, (void*(*)(void*))TestThread, (void*)NULL); if(status!=0) { printf("pthread_create ng\n"); return 1; } printf("pthread_create OK\n"); sleep(5); // スレッド停止 status = pthread_cancel(thread_test); // スレッド停止結果 if ( status != 0 ) { printf("pthread_cancel ng\n"); return 1; } printf("pthread_cancel OK\n"); sleep(5); // メッセージキューの削除 if ( msgctl( msqId, IPC_RMID, NULL) == -1 ) { printf("msqId[%d] errno[%d]\n", msqId, errno); return 1; } printf("msgctl OK\n"); sleep(5); printf("### TEST E N D ###\n"); return 0; } ----------------------------------------------------------------

  • 雛形ウィンドウ処理について

    雛形のウィンドウをGetmessage()のところとWndProcのところをトレースしたときに気づいたんですが、 Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, longtThread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartup Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), と出るのですが、まぜ順番的( Function: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x16D4 __tmainCRTStartup Function: WndProc(HWND__ *, unsigned int, unsigned int, long), Thread: 0x16D4 __tmainCRTStartupの交互 ) じゃないのはなぜなのでしょうか?あとFunction: WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int), Thread: 0x16D4 __tmainCRTStartupと Function: WndProc(HWND__ *, unsigned int, unsigned int, long), に個数に差が出るのですが、なぜなのでしょうか?

  • メッセージループについて

    while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { } } else { } これはpeekMessageがメッセージを取り出してメッセージがあったら if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) を実行して、GetMessage()で待機してもし、メッセージがWM_QUITならGetMessageにWM_QUITのメッセージを渡してメッセージが消えてPeekMessageはメッセージキューがないため、0を返し永遠にelseを繰り返すという認識でよろしいのですか? あと、while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { } if(msg.message==WM_QUIT) break; DispatchMessage(&msg); } else { } if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))がWM_QUITのメッセージで そしてメッセージが消えてGetMessageで待機状態になるということでよろしいのでしょうか?ご教授お願いします。

  • [VC++] AfxBeginThreadで生成したスレッドの監視方法について

    お世話になります。 VC++でスレッドプログラムを作っています。 AfxBeginThreadでワーカースレッドを作成し、その中でダイアログを表示する プログラムです。 問題は、ワーカースレッドがある処理状態に至ったことを メインスレッドで検知したいのですが、それがうまく いかないということです。 コードの概略をしめします。 <メインスレッド側> void CTestApp::OnTest() {   CTestDlg dlg;   dlg.IsContinue = FALSE;   pThread = AfxBeginThread(TestDlg::Thread, (void*)&dlg);   while (!dlg.IsContinue) { // <----問題:このループ処理を抜けれない!    Sleep(0);   } } <ワーカースレッド側> UINT TestDlg::Thread(LPVOID pParam){   TestDlg* pDlg = (TestDlg*)pParam;   pDlg->Create(TestDlg::IDD);   pDlg->ShowWindow(SW_SHOW);     pDlg->IsContinue = TRUE; //<--ここでフラグを変更しているのに。   while(pDlg->IsContinue) {    MSG msg;    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {      ::TranslateMessage(&msg);      ::DispatchMessage(&msg);    }   }   pDlg->DestroyWindow();   return 0; } ---- メインスレッドのSleep(0)で待つのを AfxGetApp()->PumpMessage()に変更すると ループを抜けるようなのですが、どうも納得できません。 上記のプログラムで問題、もしくはプロジェクトの 設定等に不備がある可能性がありましたら 御教授いただけたら幸いです。 よろしくおねがいいたします。

  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • ウィンドウメッセージについて

    Visual C++ で初歩のプログラミングをさせていただいてますが、 実現できない点があるのでご回答いただけると幸いです。 環境は以下になります。 SDK: Visual C++ 6.0 OS: Windows XP 今やっているのは、他のウィンドウの動きを監視するというものです。 対象のウィンドウがリサイズされたら、サイズがいくつに変更されたかメッセージボックスを出します。 以下の手順でプログラミングしました。 MSG msg; RECT r; HWND hWnd = FindWindow("Notepad", "無題 - メモ帳"); if(hWnd != NULL) { return 0; } while( GetMessage(&msg, hWnd, 0, 0) ) { if(msg.message == WM_SIZE) { GetClientRect(hWnd, &r) ... } } このように書くと、コンパイルも通ったのですが、 リサイズどころかウィンドウを動かすこともできなくなってしまいました。 こういうのって力技でしょうか・・・。 フリーソフトなどでも多いですが、ウィンドウを監視するプログラム のコアな部分はどのように書かれているものなのでしょう? よい例があればご教授よろしくお願いします。

  • 子ウインドウの作成と破棄について

    CALLBACK のみを書きました。 メインウインドウを破棄したら 子ウインドウも破棄したいのですが、 うまく出来ません。 どうすればよろしいでしょうか? よろしくお願いします。 #include<windows.h> #include"ChildWindow.h" char MainWindowClassName[]="mainwindow"; LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND childWnd; switch(message) { case WM_ACTIVATEAPP: childWnd=Child_CreateWindow(hWnd,message,wParam,lParam); break; case WM_DESTROY: DestroyWindow(childWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ///////////////////////////////////////////// #include<windows.h> char ChildWindowClassName[]="childwindow"; LRESULT CALLBACK ChildProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: MessageBox(NULL,"","",MB_OK); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ATOM Child_RegistWindow(HINSTANCE hInstance){} HWND Child_InitInstance(HWND hParentWnd,HINSTANCE hInst,int CmdShow){} HWND Child_CreateWindow(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { int CmdShow=1; Child_RegistWindow(NULL); HWND ChildWnd=Child_InitInstance(hWnd,NULL,CmdShow); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ChildWnd; }