• ベストアンサー

マルチスレッドについて

VC++を使用しています。 マルチスレッドの引数の使用法について教えてください。 int A; int B; AfxBeginThread((AFX_THREADPROC) ::WaitThread, (LPVOID)this); UINT WaitThread( LPVOID pParam ) { if(A == 0) {     … } if(A == 1) {     … } if(B == 0) {     … } if(B == 1) {     … } } のようなプログラムを作ろうとしています。 引数の受け渡し方法教えてください。 お願いします。

  • SES
  • お礼率50% (26/52)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

pParam 使わなくてもグローバルでもOKよん。 pParam を使うのは、スレッドごとに別のオブジェクトを渡したい場合で、全てのスレッドで共有する変数とかは別にグローバルでも問題ないっすよ。 問題は、変数A,Bの意味。意味によって使い分けるのが賢いよ。 余計なお世話だけど。たぶん、サンプルソースの延長線上にあるコードはバグを含むと思うよ。クリティカルセクションとかミューテックスとか調べた方がいいよ。

SES
質問者

お礼

グローバルでも試してみました。 作っているプログラムとしては、 こちらの方が使い勝手がよかったです。 ありがとうございました。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

#1の回答の通り、pParamで引数を渡すことになると思います。 ただ、pParamで単なる数値を渡すだけならよいのですが、ポインタの場合には、それが指す実体の寿命には十分気をつける必要があります。

noname#30727
noname#30727
回答No.1

pParam で渡すのが一般的だと思います。 struct MyParam { MyClass *inst; int a; int b; }; MyParam param; param.inst = this; param.a = 1; param.b = 2; AfxBeginThread((AFX_THREADPROC) ::WaitThread, (LPVOID)&param);

SES
質問者

お礼

返事遅くなってすいません。 参考にしてみます。 ありがとうございました。

関連するQ&A

  • マルチスレッド内のループについて

    こんにちは。 開発環境は VC++6.0 SDI マルチスレッドがあり、2つの処理を行う関数が書かれています。 このスレッドはダイアログボックスに配置したストップボタンを押すとフラグFALSEになりループを終了させます。 2つの関数は、int型の整数を引数にして、処理を行います。 整数はある値に達すると 0 になり永遠にループを続け、2つの処理を行います。 と言う意味合いでプログラムを書きました。(書いたつもりです) (1)この書き方ですと、for内のループが動いている時に、右上の×ボタンでダイアログを閉じると [Debug Assertion Failed!]と言う警告文が出て強制的に終了してしまいます。 ストップボタンを押してもcount=10になるまではループしています。(当然ですが・・。) そもそもマルチスレッドの中にこのような形でfor文を入れるのは間違っているのでしょうか? どのような書き方にすれば良いのでしょうか? よろしくお願い致します。 bool m_flags;//スレッド内の処理を続けるか示すフラグ UINT CabcDlg::thread(LPVOID pParam)// { CabcDlg *pInst = (CabcDlg *) pParam; while(pInst->m_flags){//ストップボタンが押されると終了する。 for (int count = 0; count<10; count++ ) { pInst->OnSend(count); //処理A pInst->OnReceive(count);//処理B } } return 0; }

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

    <プログラム環境> 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++でスレッド処理

    vc++6.0でスレッドを使ったアプリケーションを作っています。 AfxBeginThreadを使って UINT Action::reactiveMotionTh( LPVOID pvParam) {   Action *rm = (Action *)pvParam; ・   ・   ・ return 0; } CWinThread* ch = AfxBeginThread(reactiveMotionTh, (LPVOID)this); と書いたのですが、実行しようとすると、 error C2065: 'AfxBeginThread' : 定義されていない識別子です。 とエラーがでます。何が問題なんでしょうか。よろしくお願いします。

  • (マルチスレッド)_beginthreadexに複数の引数を渡す

    現在プログラムでマルチスレッドをやろうとしているのですが、 マルチスレッドの関数に数値や配列などの引数を渡すことは可能でしょうか? MSDNで調べてみると、_beginthreadex関数の4番目のNULLのところに引数リストを 指定できるとあったのですが、その意味が良くわかりませんでした。 以下のプログラムの場合にマルチスレッドに変数a, b, cを引数として渡したい場合は どのように書けばいいのでしょうか? #include <stdio.h> #include <windows.h> #include <process.h> unsigned WINAPI MyThread( void *lpx ){ while (1) { printf("スレッド実行中\n"); Sleep(1000); } return 0; } void main(){ // スレッドに渡したい変数の宣言 int a = 128; int b = 256; int c = 512; // スレッドIDの宣言 DWORD thID; // マルチスレッドの開始 (HANDLE)_beginthreadex( NULL, 0, &MyThread, NULL, 0, (unsigned int*)&thID ); // ループ while (1) { printf("メイン関数実行中\n"); Sleep(2000); } }

  • Threadの使い方について

    下記のコードは,OnButton5から、30回ThreadAを起動し、ThreadAからThreadBを起動する ものです。OnButton5の中にSleep(1)が有りますと、countXとcountA, countBは共に 30までカウントアップしますが、Sleep(1)がないと、countA, countBが30までカウントアップ しない事があります。 Q1) Sleep(1)を省略できる方法はありますか? void CMFCTHREADView::OnButton5(){ int i; for(i=0; i<LIMIT; i++){  //別途設定 #define LIMIT 30 if(SW_READYA==false){ //ThreadAがreadyになるのを待って起動する } SW_READYA=false; SetEvent(hEventA_start); //loop開始 InterlockedIncrement(&countX); //OnButton5 TRACE1("====countX=%d\n",countX); Sleep(1);//これがあると旨くいきます。 } } UINT ThreadA(LPVOID pParam){ int *pThis=reinterpret_cast<int*>(pParam); //pParam引数の受取方法 int aa=*pThis; while(SW_FIRST_LOOPX){ //=================================== if(WaitForSingleObject(hEventSW_A, INFINITE)){ //スタートコマンド待ち AfxMessageBox("time_over of hEventSW_A"); } ResetEvent(hEventSW_A); TRACE("ResetEvent(hEventSW_A)\n"); while(LOOP_ON){ //LOOP_ON is off by endOfTransferWAVE //======================= if(WaitForSingleObject(hEventA_start, INFINITE)){ //スタートコマンド待ち } ResetEvent(hEventA_start); countA++; if(SW_READYB==false){ //ThreadBがreadyになるのを待って起動する } SW_READYB=false; SetEvent(hEventB_start); //threadBの開始 TRACE1("countA=%d\n", countA); SW_READYA=true; //======================= } } return TRUE; } UINT ThreadB(LPVOID pParam){ int *pThis=reinterpret_cast<int*>(pParam); //pParam引数の受取方法 int aa=*pThis; while(SW_FIRST_LOOPX){ if(WaitForSingleObject(hEventSW_B, INFINITE)){ //スタートコマンド待ち } ResetEvent(hEventSW_B); TRACE("ResetEvent(hEventSW_B)\n"); while(LOOP_ON){ //LOOP_ON is off by endOfTransferWAVE if(WaitForSingleObject(hEventB_start, INFINITE)){ //スタートコマンド待ち AfxMessageBox("time_over of hEventB_start"); } ResetEvent(hEventB_start); countB++; TRACE1("countB=%d\n", countB); SW_READYB=true; } } return TRUE; } //================= 以上、宜しくお願いします。

  • VC++6.0 DLLの作り方

    VC++6.0でWin32 Dynamic-Link Libraryプロジェクトを作成しようとしました。 練習用に足し算と引き算です。 StdAfx.cpp test99.cpp StdAfx.h ReadMe.txt Basetsd.hなど、いろいろなファイルが出来ています。 これを親プログラムから、#include "StdAfx.h"としてリンクさせたいのですが、 StdAfx.hに、関数を公開しなければならないと思います。 StdAfx.hは、何を行うヘッダーファイルなのか? 何処に何を記述するのがベストでしょうか? VC++の生成した日本語のコメントの意味が今ひとつ理解できません。 以下はtest99.cpp #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } __declspec(dllexport) int WINAPI tasizan(int a,int b) {return (a+b);} __declspec(dllexport) int WINAPI hikizan(int a,int b) {return (a-b);} 以下はStdAfx.cpp #include "stdafx.h" 以下はStdAfx.h #if !defined(AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_) #define AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN #include <windows.h> //????????__declspec(dllexport) int WINAPI tasizan(int,int); //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。 #endif // !defined(AFX_STDAFX_H__D849B748_701B_483D_9457_AA6096D78FB0__INCLUDED_)

  • _beginthread関数の引数

    VC++ 2005 Win32コンソールアプリケーション で 1つ目のスレッドで「10」 2つ目のスレッドで「20」 3つ目のスレッドで「30」 と出力するために下記のように記述しました。 結果は予定通り出力されているのですが、 _beginthreadの第3引数の渡し方、 printfの引数の表示の仕方はこれでよいのでしょうか? void myThread(void *pParam); int arg[3] = {10, 20, 30}; int main() {   HANDLE hThread[3];   int i;   for (i = 0; i < 3; i++)   {     hThread[i] = (HANDLE)_beginthread(myThread, 0, &arg[i]);   }   /* 以下略 */ } void myThread(void *pParam) {   printf("%d\n", *(int *)pParam);   _endthread(); }

  • [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()に変更すると ループを抜けるようなのですが、どうも納得できません。 上記のプログラムで問題、もしくはプロジェクトの 設定等に不備がある可能性がありましたら 御教授いただけたら幸いです。 よろしくおねがいいたします。

  • クラスのメンバ関数の呼出しについて

    こんにちは。 初心者ですが、よろしくお願いします。 MFCを使用してダイアログベースのアプリケーションを作成しています。 <ヘッダ> class Sample : public CDialog { (略) public: int SampleA(CString); (略) <ソース> UINT SampleB(LPVOID pParam) { int n; n = Sample::SampleA(CStringA) ←エラー return 0; } メンバ関数ではない、SampleBから、上記のように呼出すと、「静的でないメンバ関数の中で呼び出しが正しくありません。」というエラーが表示されてしまいます。 ヘッダ内のメンバ関数宣言をstaticにすれば問題は解決できるのですが、このやり方しかないのでしょうか。 よろしくお願いします。

  • マルチスレッド環境での配列使用について

    現在、C++を利用してマルチスレッド環境の開発を行っています。 マルチスレッドで排他的に変数を扱う場合、クリティカルセクションや ミューテックスを使用することで、排他制御をおこなうことができますが、 このように、配列の要素ごとに排他制御を行うことは可能でしょうか? たとえば、 int ary[10]; のような配列があれば、a[0]~a[9]まで要素をそれぞれ排他制御によって データの矛盾を避けたいと考えています。 パフォーマンスの関係上、できるだけ、配列全体をロックするのは避けたいと 思っています。 どうぞよろしくお願いします。