目次に戻る
一覧ページに戻る
CPThread::BeginThread
2002/10/01 update.
Ver 1.10
スレッドを開始します。

書式

  typedef void (* LP_THREADPROC)(void *);
  CP_BOOL BeginThread(LP_THREADPROC lpProc,void *pPara);

パラメータ


lpProc
「void xxx(void *)」型のstatic関数を指定します。
pPara
lpProcで指定したstatic関数の引数に渡す情報へのポインタを指定します。
これは、任意の情報を渡すことができます。
メインの処理で使用しているデータをスレッド内でも使用したい場合は、この引数にポインタとして渡すようにしてください。
戻り値
変換処理に成功した場合は、CP_TRUEが返されます。
失敗した場合は、CP_FALSEが返されます。

解説


lpProcで指定したstatic関数をスレッド関数として、スレッドを開始します。
この「BeginThread」が実行された直後、lpProcで指定した関数はメインの処理とは別系統で並列に動作することになります。
なお、不要になった段階で、必ずスレッド関数から抜けるようにし、終了直後にスレッド関数内の最後で「EndThread」を呼び出すようにしてください。






static int g_EndFlag=0;

//スレッド関数
static void MyThreadLoop(void *lpItem)
{
    int i;
    CPThread *pThread;

    pThread=(CPThread *)lpItem;

    for(i=0;i<30;i++){

        //100ミリ秒の時間待ち
        pThread->Sleep(100);
    }

    //スレッド終了のフラグを立てる
    g_EndFlag=1;

    //スレッドの終了
    //(スレッド関数から抜ける場合には必ず呼ぶこと!)
    pThread->EndThread();
}

//メイン関数
void main()
{
    CPThread thread;

    g_EndFlag=0;

    //スレッドの開始
    thread.BeginThread(MyThreadLoop,(void *)&thread);

    //※スレッドが終了するまでは、プログラムを終えてはいけない!
    while(1){
        //スレッドが終了するまで待つ
        if(g_EndFlag) break;
    }

    //100ミリ秒の時間待ち(確実にスレッドが終了するのを待つため)
    thread.Sleep(100);
}

メインの関数の「BeginThread」にてスレッドを開始させます。
このとき、第一引数にスレッド関数「MyThreadLoop」を、第二引数にCPThreadそのもののポインタを渡しています。
この直後、スレッド関数の「MyThreadLoop」の処理が並列して行われることになります。
メイン内では、この後にwhileのループでスレッドが終了するまで無限ループするようにしています(g_EndFlagが、ループから抜けるフラグ)。
ループから抜けた後、「Sleep」にて100ミリ秒の時間待ちを行い、プログラムを終了しています。

一方、スレッド関数「MyThreadLoop」では、第一引数からCPThreadクラスのポインタを取得し、 100ミリ秒の時間待ちのループを30回行っています。
「g_EndFlag」グローバル変数にて、スレッドが終了したことをメイン関数に知らせています。
関数から抜ける直後に「EndThread」を呼び出している点に注意してください。

※「g_EndFlag」をグローバル変数として外に出して、メインとスレッド内で共用していますが、 これは、正確にはグローバル化せずに、スレッド関数の引数として渡すのが望ましいです。
上記の場合は、CPThread(thread)とg_EndFlagの2種類がありますので、「BeginThread」の第二引数で渡す場合は以下のようにします。


  int EndFlag;

  EndFlag=0;

  typedef struct {
      CPThread *pThread;
      int *pEndFlag;
  } ComInfo;
  ComInfo Info;

  Info.pThread=&thread;
  Info.pEndFlag=&EndFlag;

  thread.BeginThread(MyThreadLoop,(void *)&Info);


上記のようにした場合、 スレッド関数「MyThreadLoop」内の第一引数で「ComInfo」のポインタにキャストして、 それぞれのポインタを取得して使用するようにしてください。



static void MyThreadLoop(void *lpItem)
{
    int i;

    typedef struct {
        CPThread *pThread;
        int *pEndFlag;
    } ComInfo;
    ComInfo *pInfo;

    pInfo=(ComInfo *)lpItem;

    for(i=0;i<30;i++){

        //100ミリ秒の時間待ち
        pInfo->pThread->Sleep(100);
    }

    //スレッド終了のフラグを立てる
    *(pInfo->pEndFlag)=1;

    //スレッドの終了
    //(スレッド関数から抜ける場合には必ず呼ぶこと!)
    pInfo->pThread->EndThread();
}



ビルド時に必要なファイル


ライブラリ :CPartsLib.lib (Macintoshの場合は、CPartsCW.a)
ヘッダ :CPThread.h


関連リンク


CPThreadクラス
CPThread::EndThread
CPThread::Sleep