JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.2: C++ ユーザーズガイド
search filter icon
search icon

ドキュメントの情報

はじめに

パート I C++ コンパイラ

1.  C++ コンパイラの紹介

2.  C++ コンパイラの使用方法

3.  C++ コンパイラオプションの使い方

パート II C++ プログラムの作成

4.  言語拡張

5.  プログラムの編成

6.  テンプレートの作成と使用

7.  テンプレートのコンパイル

8.  例外処理

9.  プログラムパフォーマンスの改善

10.  マルチスレッドプログラムの構築

10.1 マルチスレッドプログラムの構築

10.1.1 マルチスレッドコンパイルの確認

10.1.2 C++ サポートライブラリの使用

10.2 マルチスレッドプログラムでの例外の使用

10.2.1 スレッドの取り消し

10.3 C++ 標準ライブラリのオブジェクトのスレッド間での共有

10.4 マルチスレッド環境での従来の iostream の使用

10.4.1 マルチスレッドで使用しても安全な iostream ライブラリの構成

10.4.1.1 公開変換ルーチン

10.4.1.2 マルチスレッドで使用しても安全な libC ライブラリを使用したコンパイルとリンク

10.4.1.3 マルチスレッドで使用しても安全な iostream の制約

10.4.1.4 マルチスレッドで使用しても安全なクラスのパフォーマンスオーバーヘッドの削減

10.4.2 iostream ライブラリのインタフェースの変更

10.4.2.1 新しいクラス

10.4.2.2 新しいクラス階層

10.4.2.3 新しい関数

10.4.3 大域データと静的データ

10.4.4 連続実行

10.4.5 オブジェクトのロック

10.4.5.1 stream_locker クラス

10.4.6 マルチスレッドで使用しても安全なクラス

10.4.7 オブジェクトの破棄

10.4.8 アプリケーションの例

10.5 メモリーバリアー組み込み関数

パート III ライブラリ

11.  ライブラリの使用

12.  C++ 標準ライブラリの使用

13.  従来の iostream ライブラリの使用

14.  複素数演算ライブラリの使用

15.  ライブラリの構築

パート IV 付録

A.  C++ コンパイラオプション

B.  プラグマ

用語集

索引

10.3 C++ 標準ライブラリのオブジェクトのスレッド間での共有

C++ 標準ライブラリ (libCstd -library=Cstd) は、いくつかのロケールを除けばマルチスレッドで使用しても安全なライブラリで、このライブラリの内部は、マルチスレッド環境で正しく機能することが保証されています。ただし、依然、スレッド間で共有するライブラリオブジェクト周りには注意を払う必要があります。setlocale(3C) および attributes(5) のマニュアルページを参照してください。

たとえば、文字列をインスタンス化し、この文字列を新しく生成したスレッドに参照で渡した場合を考えてみましょう。この文字列への書き込みアクセスはロックする必要があります。なぜなら、同じ文字列オブジェクトを、プログラムが複数のスレッドで明示的に共有しているからです。この処理を行うために用意されたライブラリの機能については後述します。

これに対して、この文字列を新しいスレッドに値で渡した場合は、ロックについて考慮する必要はありません。このことは、Rogue Wave の「書き込み時コピー」機能により、2 つのスレッドの別々の文字列が同じ表現を共有している場合にも当てはまります。このような場合のロックは、ライブラリが自動的に処理します。プログラム自身でロックを行う必要があるのは、スレッド間での参照渡しや、大域オブジェクトや静的オブジェクトを使用して、同じオブジェクトを複数のスレッドから明示的に使用できるようにした場合だけです。

ここからは、複数のスレッドが存在する場合の動作を保証するために、C++ 標準ライブラリの内部で使用されるロック (同期) 機能について説明します。

マルチスレッドでの安全性を実現する機能は、2 つの同期クラス、_RWSTDMutex_RWSTDGuard によって提供されます。

_RWSTDMutex クラスは、プラットフォームに依存しないロック機能を提供します。このクラスには、次のメンバー関数があります。

class _RWSTDMutex
{
public:
    _RWSTDMutex ();
    ~_RWSTDMutex ();
    void acquire ();
    void release ();
};

_RWSTDGuard クラスは、_RWSTDMutex クラスのオブジェクトをカプセル化するための便利なラッパークラスです。_RWSTDGuard クラスのオブジェクトは、自分自身のコンストラクタの中で、カプセル化された相互排他ロック (mutex) を獲得しようとします。エラーが発生した場合は、このコンストラクタは std::exception から派生している ::thread_error 型の例外を送出します。獲得された相互排他ロックは、このオブジェクトのデストラクタの中で解除されます。このデストラクタは例外を送出しません。

class _RWSTDGuard
{
public:
    _RWSTDGuard (_RWSTDMutex&);
    ~_RWSTDGuard ();
};

さらに、_RWSTD_MT_GUARD(mutex) マクロ (従来の _STDGUARD) を使用すると、マルチスレッドの構築時にだけ _RWSTDGuard クラスのオブジェクトを生成できます。生成されたオブジェクトは、そのオブジェクトが定義されたコードブロックの残りの部分が、複数のスレッドで同時に実行されないようにします。単一スレッドの構築時には、このマクロは空白の式に展開されます。

これらの機能は、次のように使用します。

#include <rw/stdmutex.h>

//
// An integer shared among multiple threads.
//
int I;

//
// A mutex used to synchronize updates to I.
//
_RWSTDMutex I_mutex;

//
// Increment I by one. Uses an _RWSTDMutex directly.
//

void increment_I ()
{
   I_mutex.acquire(); // Lock the mutex.
   I++;
   I_mutex.release(); // Unlock the mutex.
}

//
// Decrement I by one. Uses an _RWSTDGuard.
//

void decrement_I ()
{
   _RWSTDGuard guard(I_mutex); // Acquire the lock on I_mutex.
   --I;
   //
   // The lock on I is released when destructor is called on guard.
   //
}