SHOEISHA iD

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

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

インテルTBBを通じて学ぶ並列処理

インテルTBBのスレッドクラス

インテルTBBを通じて学ぶ並列処理(4)


  • X ポスト
  • このエントリーをはてなブックマークに追加

スレッドクラス

 インテルTBBには豊富な機能があり、大概の並行処理はそれを使用すれば解決できるでしょう。しかし、あらかじめインテルTBBに用意されている並列アルゴリズムを適用できない状況で、並列処理をする必要があるかもしれません。この場合は、インテルTBBに用意されているthreadクラスの使用を検討する必要があります。

 これからインテルTBBのスレッドを使用するサンプルプロジェクトThreadSampleのコードを掲載するので、まずはそのコードを見てください。

インテルTBBのスレッドクラスの使用法
#include <iostream>
#include "tbb/compat/thread"
using namespace std;

/*-------------------------------------------------------------------------------

    スレッドの使用法を示す為だけのクラス

----------------------------------------------------------------------------------*/
class Foo 
{
public:
    /*
        スレッドが行う処理を、関数呼び出し演算子にコーディングします。
    */
    void operator()() const 
    {
        cout << "Fooオブジェクトの関数呼び出し演算子が呼び出されました。" << endl;
    };
};

/*-------------------------------------------------------------------------------

    メインプログラム

----------------------------------------------------------------------------------*/
int main(void) 
{
    Foo obj; //オブジェクトを初期化
    thread fooThread( obj ); //オブジェクトを指定
    fooThread.join(); //待機する

    cout << endl;
}

 このサンプルは、インテルTBBのスレッドを使用して処理を実行する簡単なものです。このコードを理解すれば、インテルTBBのスレッドを使用する方法が分かります。これからその手順を解説します。

 インテルTBBのスレッドを使用して並列処理をする為に必要な準備は、並列処理を行いたいオブジェクト(以後、並列オブジェクトと呼びます)に「メソッド呼び出し演算子」を定義するだけです。

 準備が終わったら、並列オブジェクトを初期化してから、並列オブジェクトを指定してthreadオブジェクトを初期化します。後は、threadオブジェクトのjoinメソッドを実行すれば、並列的に処理が実行された処理を待ちます。これでインテルTBBのスレッドを動かすことができるようになったので、次項ではthreadオブジェクトに用意されているメソッドについて解説します。

スレッドのスリープ概要

 複数のスレッドを使って並列処理をする時、単純な処理しかしないスレッドが実行され続けることを避けたい状況があります。この時、任意のスレッドをスリープできると便利です。スレッドのスリープとは、スレッドの処理を一時停止することです。何故スリープする必要があるのかは後で解説します。

 インテルTBBのスレッドにもこの機能はあります。これから、サンプルプロジェクトSleepSampleのコードを提示するので、まずはコードを読んでください。

sleep_forメソッドの使用法を示すサンプル
#include <iostream>
#include "tbb/compat/thread"
using namespace std;

/*-------------------------------------------------------------------------------

    sleep_forメソッドの使用法を示す為だけのクラス

----------------------------------------------------------------------------------*/
class SlowFoo 
{
public:
    /*
        スレッドが行う処理を、関数呼び出し演算子にコーディングします。
    */
    void operator()() const 
    {
        this_thread::sleep_for( tbb::tick_count::interval_t( 2.0 ) ); //2秒以上スリープ
        cout << "SlowFooオブジェクトが漸く処理をしました。" << endl;
    };
};

/*-------------------------------------------------------------------------------

    メインプログラム

----------------------------------------------------------------------------------*/
int main(void) 
{
    cout << "処理を開始しました・・・" << endl;
    SlowFoo obj; 
    thread fooThread( obj ); 
    fooThread.join(); 
    cout << "処理が終了しました。" << endl;

    cout << endl;
}

 このサンプルを実行すると、2秒ぐらい経過してからメッセージが表示されます。注目するべき点はこの部分です。

this_thread::sleep_for( tbb::tick_count::interval_t( 2.0 ) ); //2秒以上スリープ

 スリープしたいスレッドのメソッド内で、this_thread::sleep_forを実行すると、指定値以上の秒数スリープされます。指定値秒ではない点に注意してください。WindowsはリアルタイムOSではないので、正確な時間を指定してスレッドを実行することはできません。

 スリープが必要な理由は、この機能が存在しないと、ビジーウェイトをするしかなくなるからです。ビジーウェイトというのは、変数がある値になるまでループ上でチェックすることです。ビジーウェイトはCPUを消費しますし、予期せぬ結果を生みますので、あまり使用されません。ビジーウェイトをする代わりに、スリープを使用するとCPUをビジーウェイトよりも消費しなくなり、ビジーウェイトで発生する並列処理特有のバグも避けられます。

 これで、スリープに関する解説は終了です。次項では、スレッド切り替えについて解説します。

次のページ
スレッドの切り替え

修正履歴

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
インテルTBBを通じて学ぶ並列処理連載記事一覧

もっと読む

この記事の著者

インドリ(インドリ)

分析・設計・実装なんでもありのフリーエンジニア。ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。座右の銘は温故知新で、新旧関係なく必要だと考えたものは全て学...

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5259 2010/07/13 10:03

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング