3


3

pthreadから始めて、pthread_key_tとpthread_once_tのビジネスが理解できないのですが。

可能であれば、誰かが簡単な言葉で例を挙げて説明しますか。

ありがとう

3 Answer


12


pthread_key_t`は、スレッドを作成するためのものです。http://en.wikipedia.org/wiki/Thread-local_storage[thread-local storage]:各スレッドは、グローバル(または関数を共有するすべてのスレッドではなく)独自のデータ変数のコピーを取得します。静的、クラス静的)変数。 TLSはキーによって索引付けされています。 詳細についてはhttps://computing.llnl.gov/tutorials/pthreads/man/pthread_getspecific.txt [`pthread_getspecific]他をご覧ください。

pthread_once_t`はhttps://computing.llnl.gov/tutorials/pthreads/man/pthread_once.txt [ pthread_once`]で一度だけ関数を実行するためのコントロールです 初期化ルーチンを呼び出す必要があるとしますが、そのルーチンは1回だけ呼び出す必要があります。 さらに、それを呼び出さなければならないのは、すでに複数のスレッドを起動した後です。 これを行う1つの方法は `pthread_once()`を使用することです。これは各呼び出しで同じ制御変数を使用する限り、一度にいくつのスレッドがそれを呼び出そうとしていてもルーチンが一度だけ呼び出されることを保証します。 。 他の方法を使うよりも、pthread_once()の方が簡単なことがよくあります。


11


いいえ、それは素人用語で説明することはできません。 素人はCのpthreadsでうまくプログラムできません。 それは "コンピュータプログラマー"として知られている専門家を取ります:-)

pthread_once_t`は pthread_once`がそれが錫の言うことを確実にするためにアクセスしなければならない少しのストレージです。 1回の制御ごとにinitルーチンを1回だけ呼び出すことができます。これは、いくつのスレッドから(おそらく同時に)何回呼び出されても同じです。 通常、オンデマンドで初期化することを計画している各オブジェクトに対して、スレッドセーフな方法で異なるonceコントロールを使用します。 あなたは事実上、スレッドがinitをするために選択されたかどうかのフラグとして原子的にアクセスされる整数として考えることができます。 しかし、 pthread_once`がブロックしているので、実装が同期プリミティブに詰め込むことができるのであれば、それ以上のことが許されると思います( pthread_onceを実装した唯一の時間ではありません)制御は3つの状態(開始、初期化、終了)のいずれかを取りました。 しかし、それから私はカーネルを変えることができませんでした。 異常な状況)

`pthread_key_t`はスレッドローカルストレージにアクセスするためのインデックスのようなものです。 各スレッドはキーから値へのマップを持っていると考えることができます。 TLSに新しいエントリを追加するとき、 `pthread_key_create`はそれに対するキーを選び、そのキーを指定した場所に書き込みます。 現在のスレッドに対してそのTLS項目の値を設定または取得するときはいつでも、そのスレッドからそのキーを使用します。 TLSがあなたに選択させるのではなく鍵を与える理由は、無関係のライブラリが、同じ値を使うことと互いのTLSデータを捨てることを避けるために協力する必要なしに、TLSを使うことができるためです。 pthreadライブラリは、例えばグローバルカウンタを保持し、最初に `pthread_key_create`が呼ばれるときには0を、2番目には1を割り当てるという具合です。


2


うわー、他の答えはあまりにも冗長すぎる。

pthread_once_t`は pthread_once() `の状態を保存します。 `pthread_once(を呼び出す その後の `pthread_once()`の呼び出しはすべてnoopsです。 名前がわかりやすくなります。

pthread_once_t`は PTHREAD_ONCE_INIT`に初期化されるべきです。