WideStudio Programming Guide

| WideStudio Programming Guide | WideStudio Index 目次

> ## ロースレッド/セマフォ/ミューテックス

> ### ロースレッドクラスを用いたスレッドの生成

> WSDthread クラスを利用するとプログラム上からスレッドを生成することが できます。
> btnop() 関数がボタンなどの押下により実行されるイベントプロシージャ本体です。 そのイベントプロシージャ上で WSDthread クラスのインスタンスを生成し、 スレッドとして実行する関数 thread_func() を指定し、 スレッド生成を行ないます。 また、スレッドとして動作する thread_func() 上から、execCallback() メンバ関数を 用いてメインスレッドにイベントを通知することができます。 execCallback() メンバ関数を呼び出すと、メインスレッド上で、 setCallbackFunction() メンバ関数で指定されたコールバック関数が動作し、 スレッドとメインスレッドと同期処理を行なうことができます。

>     #include <WScom.h>
>     #include <WSCfunctionList.h>
>     #include <WSCbase.h>
>     //----------------------------------------------------------
>     //Function for the event procedure
>     //----------------------------------------------------------
>     WSDthread* thr = NULL;

>     //サブスレッドとして実行する関数の定義
>     void* thread_func(WSDthread* obj,void* ptr){
>       long cnt= (long)ptr;
>       while(1){
>         cnt++;
>         obj->execCallback((void*)cnt); // メインスレッドへ通知
>     #ifdef MSW
>         Sleep(1000);
>     #else
>         sleep(1);
>     #endif
>       }
>       return NULL;
>     }

>     //スレッドから通知され、メインスレッドで実行されるコールバック
>     void callback_func(WSDthread*,void* val){
>       long cnt = (long)val;
>       //カウントアップされた内容を表示します。
>       newvbtn_000->setProperty(WSNlabelString,cnt);
>     }

>     //イベントプロシージャ。ボタン押下などで実行。
>     void btnop(WSCbase* object){
>       if (thr == NULL){
>         thr = WSDthread::getNewInstance();
>         thr->setFunction(thread_func);
>         thr->setCallbackFunction(callback_func);
>         thr->createThread((void*)100);
>       }else{
>         exit(0);
>       }
>     }

> createThread() メンバ関数によって起動されたスレッド内では、 メインスレッドとは非同期のサブスレッドとして動作するため、 スレッドアンセーフであるWideStudio の GUI インスタンスに対して 排他制御無しに操作してはいけません。 WideStudio の GUI インスタンスに対して スレッド内で処理を行なった結果を表示させたい場合等は、 スレッドインスタンスに対して execCallback() メンバ関数を 用いて、 メインスレッドに通知する手段を用い、メインスレッド上で表示処理を 行ないます。

> ### ミューテックス

> ミューテックスを用いて、複数のスレッドが動作するコードに対して、 同時に1スレッドしか、動作させないよう、排他することができます。 下記の例は、ロースレッドを用いて生成された複数のスレッドの実行される中、 同時に複数が実行されては困る処理に対して、 ミューテックスを用いて排他をかけている例です。

>     #include <WScom.h>
>     #include <WSCfunctionList.h>
>     #include <WSCbase.h>
>     #include <WSDthread.h>
>     #include <WSDmutex.h>
>     #include <stdlib.h>
>     #include <unistd.h>
>     //----------------------------------------------------------
>     //Function for the event procedure
>     //----------------------------------------------------------
>     #include <newwin000.h>
>     WSDmutex* mutex = NULL;
>     static long cnt=0;

>     //複数のサブスレッドとして実行する関数の定義
>     void* thread_func(WSDthread* obj,void*){
>       while(1){
>         mutex->lock();
>         cnt++;
>         obj->execCallback((void*)cnt); // メインスレッドへ通知
>     #ifdef MSW
>         Sleep(1000);
>     #else
>         sleep(1);
>     #endif
>         mutex->unlock();
>       }
>       return NULL;
>     }

>     //スレッドから通知され、メインスレッドで実行されるコールバック
>     void callback_func(WSDthread*,void* val){
>       long cnt = (long)val;
>       //カウントアップされた内容を表示します。
>       newvbtn_000->setProperty(WSNlabelString,cnt);
>     }

>     //イベントプロシージャ。ボタン押下などで実行。
>     void btnop(WSCbase* object){
>       //do something...
>       if (mutex == NULL){
>         //排他を行なうためのミューテックスを生成します。
>         mutex = WSDmutex::getNewInstance();
>         mutex->initialize();

>         //同時に10のスレッドを生成し、数値をカウントアップします。
>         long i;
>         for(i=0; i<10; i++){
>           WSDthread* thr = WSDthread::getNewInstance();
>           thr->setFunction(thread_func);
>           thr->setCallbackFunction(callback_func);
>           thr->createThread((void*)0);
>         }
>       }else{
>         exit(0);
>       }
>     }
>     static WSCfunctionRegister  op("btnop",(void*)btnop);

> ### セマフォ

> セマフォを用いて、 ミューテックスと同様な排他を行なう場合、または、複数のスレッドが 協調動作を行なうために待ち合わせを処理を行なうことが できます。 下記の例は、ロースレッドを用いて生成されたスレッドに対し、 セマフォを用いて待ち合わせを行なう例です。 ボタンを1度押下すると、スレッドを生成し、 セマフォを用いてスレッドを待機させます。 2度目の押下でセマフォを解除し、待機させておいたスレッドを動作を開始させます。

>     #include <WScom.h>
>     #include <WSCfunctionList.h>
>     #include <WSCbase.h>
>     #include <WSDthread.h>
>     #include <WSDsemaphore.h>
>     #include <stdlib.h>
>     #include <unistd.h>
>     //----------------------------------------------------------
>     //Function for the event procedure
>     //----------------------------------------------------------
>     #include <newwin000.h>
>     WSDsemaphore* sem = NULL;
>     static long cnt=0;

>     //スレッドとして動作する関数です。
>     void* thread_func(WSDthread* obj,void* val){
>       sem->lock(); //セマフォで待ち合わせをします。
>       while(1){
>         obj->execCallback((void*)cnt);
>     #ifdef MSW
>         Sleep(1000);
>     #else
>         sleep(1);
>     #endif
>         cnt++;
>       }
>       return NULL;
>     }

>     //スレッドから通知され、メインスレッドで実行されるコールバック
>     void callback_func(WSDthread*,void* val){
>       long cnt = (long)val;
>       //カウントアップされた内容を表示します。
>       newvbtn_000->setProperty(WSNlabelString,cnt);
>     }

>     //イベントプロシージャ。ボタン押下などで実行。
>     void btnop(WSCbase* object){
>       //do something...
>       if (sem == NULL){
>         //セマフォを作成します。
>         sem = WSDsemaphore::getNewInstance();
>         sem->initialize();
>         sem->lock();

>         //スレッドを生成します。
>         WSDthread* thr = WSDthread::getNewInstance();
>         thr->setFunction(thread_func);
>         thr->setCallbackFunction(callback_func);
>         thr->createThread((void*)0);
>         object->setProperty(WSNlabelString,"Start Thread");
>       }else{
>         //2度目の実行時にセマフォを解除し、待ち合わせていたスレッドを動作させます。
>         sem->unlock(); //start the waiting thread.
>       }
>     }
>     static WSCfunctionRegister  op("btnop",(void*)btnop);

Document Release 3.70 for WideStudio ver 3.70, May 2004

WideStudio documents index | 目次

Copyright(C) WideStudio Development Team, 1999-2004 | Last modified: May 25, 2004