SHOEISHA iD

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

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

japan.internet.com翻訳記事

C++0xのマルチスレッド機能

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

 C++の新しい標準規格である「C++0x」には、マルチスレッドをサポートする新しいライブラリがあります。移植性を高め、使用するAPIや構文を減らすことのできるこの新機能について紹介します。

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

はじめに

 C++の新しい標準規格である「C++0x」の大きな新機能の1つが、マルチスレッド処理のサポートです。

 従来のC++では、マルチスレッド機能は標準規格の拡張としてコンパイラごとに提供されていたため、細かな部分がコンパイラやプラットフォームによって異なっていました。しかしC++0xでは、すべてのコンパイラが同じメモリモデルに準拠し、同一のマルチスレッド機能を利用できることになります(ただし、従来同様の拡張をコンパイラが独自に提供することも可能です)。

 開発者の立場からすると、マルチスレッドのコードを別のコンパイラやプラットフォームへ移植するときの手間を大きく省くことができます。複数のプラットフォーム向けの開発を行う場合でも、種々雑多なAPIや構文をいくつも頭に入れておく必要がありません。

 新しいスレッドライブラリの中心を担うのは、実行スレッドを制御するstd::threadクラスです。まずはこれから見ていくことにしましょう。

スレッドの起動

 新しいスレッドを起動するには、std::threadのインスタンスを生成し、関数を引数に渡します。この関数は新しいスレッドのエントリポイントとなります。この関数から処理が戻ると、スレッドも終了します。

void do_work();
std::thread t(do_work);

 これだけ見ると、従来使用してきたスレッド生成用のAPIと大差ありません。しかし、大きな違いが1つあります。C++なので、渡せるのは関数だけとは限らないという点です。標準C++ライブラリの各種アルゴリズムと同じで、関数呼び出し演算子(operator())を実装したクラスのオブジェクトを、通常の関数と同様にstd::threadに渡すことができるのです。

class do_work
{
public:
    void operator()();
};

do_work dw;
std::thread t(dw);

 この処理では、引数に渡したオブジェクトがスレッド内に実際にコピーされるという点が要注意です。指定したオブジェクトそのものを参照渡しで使いたい場合は、std::refでラップします(ただしその場合、スレッドの完了前にそのオブジェクトを破棄することがないよう注意が必要です)。

do_work dw;
std::thread t(std::ref(dw));

 大抵のスレッド作成APIでは、作成するスレッドに対して1つのパラメータ(通常はlong値やvoid*値)を渡します。std::threadにも引数を渡せますが、数の制限はなく、ほぼすべての型を使用できます。「数の制限がない」という点が大きな特徴です。C++0xで新たに導入された可変個引数テンプレート(Variadic Templates)機能をコンストラクタで使うことで、可変個の引数に対応できます(リンク先はPDF)。構文は従来のvararg(...)と似ていますが、タイプセーフな処理が可能です。

 では、コピー可能な任意の型のオブジェクトを、スレッド関数に引数として渡してみましょう。次のようになります。

void do_more_work(int i,std::string s,std::vector<double> v);
std::thread
    t(do_more_work,42,"hello",std::vector<double>(23,3.141));

 関数オブジェクト単独の場合と同様に、各引数は関数の呼び出し前にスレッドにコピーされます。参照渡しにしたい場合はstd::refでラップします。

void foo(std::string&);
std::string s;
std::thread t(foo,std::ref(s));

 スレッドの起動についてはこれくらいにして、次はスレッド終了の待機です。C++標準ではこれを、POSIXの用語にならって、スレッドの「ジョイン(join)」と呼んでいます。使用するメンバ関数はjoin()です。

void do_work();
std::thread t(do_work);
t.join();

 スレッドのジョインを行わない場合は、スレッドオブジェクトを単に破棄するか、detach()を呼び出します。

void do_work();
std::thread t(do_work);
t.detach();

 こうしてスレッドを起動および終了できますが、スレッド間でデータを共有するとしたら、保護のための処理も必要になります。新しいC++標準ライブラリにはそのための機能もあります。

会員登録無料すると、続きをお読みいただけます

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

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

メールバックナンバー

次のページ
データの保護

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

  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

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

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

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

Anthony Williams(Anthony Williams)

Just Software Solutions Ltd.のテクニカルディレクター。顧客向けのカスタムソフトウェア開発に主に従事。WindowsおよびC++による開発が中心。Boost Threadライブラリのメンテナーで、BSI C++ Standards Panelのメンバーでもある。近刊の『C+...

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

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

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3287 2008/12/01 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング