SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

C++でのスレッドクラスの作成

プラットフォームに依存しないスレッド処理をC++で実現する方法

ダウンロード サンプルソース (13.2 KB)

CTaskクラスと非細分型スレッド

 これまで私が目にしたスレッドプログラミングの例の多くは、スレッド処理用のデータをグローバル変数に格納し、ミューテックスで保護するという形でした。データを操作する処理はスレッド関数に組み込まれています。私は、そのような形のスレッド処理を、「細分型非同期スレッド処理(SAT:Specialized Asynchronous Threading)」と呼んでいます。

 しかし実際には、データとその処理機能は同じオブジェクトにカプセル化されているのが理想です。私は、そのような形のスレッド処理を、「均一型非同期スレッド処理(HAT:Homogeneous Asynchronous Threading)」と呼んでいます。HATでは、各スレッドは細分化されていません。たとえば、HATのソリューションでは、印刷スレッド、I/Oスレッド、という分類はありません。代わりに、単一のスレッドで両方の種類のタスクに対応できます。タスクは、すべてを完備したオブジェクトとして実装されている(つまり、データ自体とその処理に必要な機能の両方がひとまとまりになっている)からです。CTaskクラスは、HATベースのスレッド処理を扱いやすくするための基本クラスです。

typedef enum {
   TaskStatusNotSubmitted,
   TaskStatusWaitingOnQueue,
   TaskStatusBeingProcessed,
   TaskStatusCompleted } TaskStatus_t;

class CTask
{
private:
   CMutexClass m_mutex;
   TaskStatus_t m_state;
   ThreadId_t m_dwThread;
public:
   void SetTaskStatus(TaskStatus_t state)
   {
      m_mutex.Lock();
         m_state=state;
      m_mutex.Unlock();
   }

   void SetId(ThreadId_t *pid)
   {
      memcpy(&m_dwThread,pid,sizeof(ThreadId_t));
   }

   /**
    *
    * Wait
    * waits for up to timeoutSeconds for a task
    * to complete
    *
   **/
   BOOL Wait(int timeoutSeconds)
   {
      timeoutSeconds = timeoutSeconds * 1000;
      if( Status() != TaskStatusCompleted &&

          timeoutSeconds > 0 )
      {
         Sleep(100);
         timeoutSeconds = timeoutSeconds - 100;
      }
      if( Status() == TaskStatusCompleted ) return TRUE;
      return FALSE;
   }

   /**
    *
    * Where
    * returns current state of a task
    *
    **/
   TaskStatus_t Status()
   {
      TaskStatus_t state ;

      m_mutex.Lock();
        state = m_state;
      m_mutex.Unlock();
      return state;
   }

   void Thread(ThreadId_t *pId)
   {
      memcpy(pId,&m_dwThread,sizeof(ThreadId_t));
   }

   CTask(){m_state=TaskStatusNotSubmitted;
           memset(&m_dwThread,sizeof(ThreadId_t),0); }
   ~CTask(){}
   virtual BOOL Task()=0;
};
メンバ関数
関数説明
m_mutexオブジェクト同期用のミューテックスオブジェクト
virtual BOOL Task()タスクを実行するためにCThreadオブジェクトから呼び出される
TaskStatus_t Status()タスクの状態(TaskStatusNotSubmitted、TaskStatusWaitingOnQueue、TaskStatusBeingProcessed、TaskStatusCompleted)を判断する
void Thread(ThreadId_t *pid)処理しているスレッドのスレッドIDを返す
BOOL Wait(int iTimeInSeconds)タスクが完了するかiTimeInSecondsが経過するまで、呼び出し元のスレッドを待ち状態にする。iTimeInSeconds内にタスクが完了しない場合はFALSEが返る。それ以外の場合はTRUEが返る

 CThreadクラスをまだ定義していませんが、CThreadオブジェクトとCTaskオブジェクトがどのように連係するかは、定義がなくても理解できます。これら2つのオブジェクト型の連係の概要を次に示します。

CTaskオブジェクトの処理手順

  1. CTaskオブジェクトが処理のためにCThreadオブジェクトに渡される
  2. CThreadオブジェクトがCTaskオブジェクトを先着順(FVFS:First Come First Served)方式のキューに格納する
  3. CThreadオブジェクトがCTaskオブジェクトの状態をTaskStatusWaitingOnQueueに設定する
  4. CThreadオブジェクトが待機キューからCTaskオブジェクトをポップする
  5. CThreadオブジェクトがCTaskオブジェクトの状態をTaskStatusBeingProcessedに変更する
  6. CThreadオブジェクトがCTaskオブジェクトのメンバ関数taskを呼び出してタスクを実行する
  7. CThreadオブジェクトがCTaskオブジェクトの状態をTaskStateCompletedに変更する

次のページ
メインのCThreadクラス

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Walter Capers(Walter Capers)

Compuware社のソフトウェアアーキテクトで、ソフトウェアセキュリティを専門としている。言語はC/C++、FORTRAN、COBOL、Java。ライブラリはOpenGL、MFC、WIN32。経験のあるプラットフォームはAIX、HP-UX、SunOS、Open VMS、OSF、AS400、AIX、...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1977 2008/01/08 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー