質問

Cライブラリにグローバルな静的変数があり、マルチスレッド実行で例外を生成します。何らかの方法でそれらを安全にする必要があります(つまり、各スレッドはこれらの変数の異なるインスタンスに関連する必要があります)。推奨される方法はありますか?

役に立ちましたか?

解決

すべてのC実装で機能する標準的な方法はありませんが、実装固有のソリューションが存在します。たとえば、Microsoftのコンパイラを使用してください(参照してください ドキュメント),

__declspec( thread ) int tls_i = 1;

作る tls_i スレッドローカルストレージに住んでいます(各スレッドには、この変数の独自のインスタンスがあります)。と GCC, 、構文はです

__thread int tls_i;

また、確認することもできます ウィキペディアエントリ 件名に。

他のヒント

最初の質問:

  • スレッドには変数のコピーが必要ですか?
  • または、1つの共有コピーへのアクセスを調整する必要がありますか?

前者が必要な場合、他の答えは「スレッドローカルストレージ」について提案しました。

後者が必要な場合は、どういうわけか、それらの変数に適切なミューテックスがあることを確認する必要があります(Mutexの範囲は直面する問題の1つです)。これは難しいです。変数へのアクセスを制御する関数を提供する必要があるかもしれません。

標準変数 errno 変更可能なlvalueにすることができます:

extern int *_errno_func(void);
#define errno (*(_errno_func)())

スレッドアプリケーション(-dreentrantでコンパイル)では、これが起こることです。 MacOS Xでは、とにかく起こることのように見えます(彼らは名前を使用しています __error それ以外の _errno_func;どちらも実装の名前空間にあります)。

変数に対して同様のことをしたい、またはしなければならない場合があります。あなたが彼らが静的であると言うという事実は、物事を少し改善します。処理するファイルは1つだけです(それらの変数へのパスバックまたはオン - ポインターを渡すのに十分な不注意でない限り)。

あなたが必要としていたのはです TLS(ローカルストレージをスレッド), 、とも呼ばれます スレッド固有のデータ また スレッドプライベートデータ. 。このメカニズムは、他のスレッドとのアクセスの同期を心配することなく、各スレッドが独自の個別のコピーにアクセスすることを保証できます。


TLSを使用する2つの方法があります。

  1. 暗黙的:キーワードの使用

    ウィンドウズ: __declspec(thread)int tls_var = 10;

    GCCのLinux: __thread int tls_var = 10

  2. 明示的:特定のTLS関連APIを使用します

    ウィンドウズ:

      tlsalloc(): TLSデータにメモリを割り当てます
      tlsfree(): TLSデータのメモリを解放します
      tlssetValue(): TLSの値を設定します
      tlsgetValue(): TLSの値を取得します

    詳細については、MSDNを参照してください。

    GCCのLinux:

      pthread_key_create(): :TLSデータを作成します
      pthread_key_delete(): :TLSデータを不快にします
      pthread_getSpecific(): :TLSの値を取得します
      pthread_setspecific():TLSの値を設定します
    具体的で詳細な情報については、マンページに移動します。

ほとんどのコンパイラには、スレッドローカルストレージを指定する方法があります。それが利用可能であると仮定すると、それがあなたが望むものです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top