問題タブ [thread-local-storage]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - グローバル変数を持つシングルスレッドのレガシーコードを、スレッドローカルストレージを使用してマルチスレッドコードに変換する
私はレガシーC/C ++コードのコードベースを持っています。これには、グローバル静的変数にアクセスする多くの関数が含まれているため、スレッドセーフではありません。このコードをスレッドセーフにする方法についてのアドバイスを探しています。そのための1つの方法は、静的変数をスレッドローカル変数に変換するか、スレッドローカルストレージに格納することです。これには、関数を使用して追加のコンテキストを渡すコードをたくさん書き直す必要がなく、スレッドセーフでない関数自体だけを書き直す必要がないという利点があります。しかし、これを調査したところ、これが良いアイデアか悪いアイデアかについてのアドバイスはあまり見つかりませんでした。私が持っているいくつかの特定の懸念は
- TLSベースのデータへのアクセスは大幅に遅くなりますか?
- am I just continuing to fall into the trap of using global variables, since "global variables are bad", or does TLS counteract the global-variables-are-bad argument?
Any other thoughts would be appreciated too.
c++ - C++コンパイラはC++0xでスレッドローカルストレージをどのように実装しますか?
c++コンパイラはC++0xでスレッドローカルストレージをどのように実装しますか
私はこれをグーグルで検索しました。しかし、私はこれについて何も見つけることができません。
誰もこれについて何か資料を持っていますか??
.net - log4net.ThreadContextとlog4net.LogicalThreadContextの違いは何ですか?
2014年11月18日に更新-log4netソースリポジトリを参照しているときに、LogicalThreadContextの実装が2011年11月に変更され、CallContext.LogicalSetDataを使用してプロパティを格納する(そしてLogicalGetDataを使用して取得する)ことがわかりました。これは、LogicalThreadContextが正しく機能するようになることを意味するため重要です。LogicalThreadContextに格納されているデータは、子スレッドまたはタスクに「フロー」する必要があります。これは、コンテキストに格納されたデータが現在のスレッドに対してローカルのままであり、子スレッド/タスクにフローされないThreadContext(およびLogicalThreadContextの古い実装)と比較されます。
興味がある場合は、次の変更があります。
うまくいけば、この古い質問に遭遇した誰かがこの情報が役立つと思うでしょう。
log4netは、2つの異なる「スレッドコンテキスト」オブジェクトを提供します 。ThreadContextとLogicalThreadContextで、それぞれにプロパティバッグPropertiesがあります。ThreadContextにはThreadContextPropertiesバッグがあり、LogicalThreadContextにはLogicalThreadContextPropertiesバッグがあります。
ThreadContextは、おそらくより一般的に「MDC」として知られています。論理コンテキストは、おそらくより一般的に「LDC」として知られています。この投稿の残りの部分では、短い名前を使用します。
MDC.PropertiesはSystem.Threading.Thread.SetDataを使用して実装され、LDC.PropertiesはSystem.Runtime.Remoting.Messaging.CallContext.SetDataを使用して実装されます。
比較のために、NLogはスレッドローカルプロパティを格納するために「MDC」(現在はMappedDiagnosticContextとして知られています)のみを公開します。NLogの実装はSystem.Threading.Thread.SetDataを使用するため、その実装はlog4netの実装と同じです。
log4netとNLogの両方で、「MDC」プロパティはディクショナリに格納され、ディクショナリ自体はスレッドローカルストレージに格納されます。
このような場合、[ThreadStatic]で装飾されたクラスメンバー変数に辞書を格納することは同等でしたか?
.NET 4.0の新しいThreadLocalクラスを使用した同等の(または同様の)宣言は何ですか?
最終的に、LDCとMDCの実際の実用的な違いは何ですか?上記のリンク先のMSDNトピックを読んだ後でも、私にはわかりません。いつ実際に一方を他方の上に使用しますか?log4netとコンテキストで見られる参照/例の大部分は、GDC(グローバル-私が理解している)、NDC(ネストされている-私も理解している)、およびMDCのもののようです。グーグルでLDC(またはLogicalThreadContext)を見つけることができるほとんどの参照は、実際の使用法ではなく、log4netソースコードリポジトリへのチェックインに関連しています。LDCが質問や例で登場することはほとんどありません。
log4net開発者の1人であるNickoCadellとの違いについて、かなり良い情報を提供するこのリンクを見つけましたが、それでも私にはわかりません。
log4netに直接関係しない、より大きな質問は、Thread.SetDataとCallContext.SetDataの実際的な違いは何ですか?
CallContext MSDNの記事によると、CallContextデータは別のAppDomainに伝播できます。伝播するには、CallContextに格納されているデータ項目がILogicalThreadAffinativeインターフェイスを公開する必要があります。つまり、これがThread.SetDataとCallContextの違いの1つであるように思われます。
Nicko Cadellリンクによると、log4netはILogicalThreadAffinativeを実装していないため、LDCプロパティは伝播されません。
たぶん、ここには私自身の質問に答えられるはずの十分なものがあるかもしれませんが、そうではないかもしれません。私はまだ理解に取り組んでいます。
log4netを使用する場合、すべてMDC、LDC、両方を使用しますか?MDCを使用している場合、それは「実世界」の例のほとんどがMDCを使用しているように見えるためですか。LDCを使用している場合、それを使用する特定の理由がありますか?両方を使用する場合、どちらをいつ使用するかをどのように選択しますか?
MDC(およびおそらくLDC)に関するいくつかの記事が、スレッドの切り替えが原因でASP.netアプリケーションで正しく機能しない可能性があることに注意してください。私はASP.netで作業していないため、この問題には特に関心がありません。
実際、私はここSOで、議論に貢献するかもしれないいくつかの有用な投稿を見つけました。
.NETでスレッドローカルストレージを使用するためのベストプラクティスは何ですか?
前もって感謝します!
multithreading - g++ を使用して 64 ビット Solaris sparc でスレッド ローカル ストレージ (TLS) をコンパイルする方法
スレッド ローカル ストレージに __thread キーワードを使用する C/C++ コードがありますが、64 ビット Solaris Sparc で g++ (バージョン 4.0.2) を使用してコンパイルするのに問題がありますが、Linux では g++ を使用してコンパイルおよび実行できます。 34コンパイラ。ソースコードの例を次に示します。
「g++ -dumpversion」コマンドからのコンパイラ情報は「4.0.2」を返し、「g++ -dumpmachine」は「sparc-sun-solaris2.8」を示します。「uname -a」は「SunOS devsol1 5.9 Generic_118558-26 sun4u sparc SUNW,UltraAX-i2」を表示します。
g ++でmakeを実行している間のエラーメッセージは次のとおりです:「エラー:このターゲットではスレッドローカルストレージはサポートされていません」、使用しているコンパイラオプションは
私は週末にこれに苦労しており、締め切りに直面しているため、どんな助けも大歓迎です.
ありがとう、チャールズ
linux - ELF ファイルの TLS および LOAD プログラムのセクション
-static
コンパイル後readelf -l
、elf からのプログラム ヘッダーが表示されます。
2番目と4番目のプログラムヘッダーが交差する理由を誰かが説明できますか(同じオフセット0x079f94とVirtAddr 0x080c2f94で始まります)。
また、セグメントセクション.tdata
は 2 回参照されます。
最初のスレッド (プログラム自体) にどのようPT_TLS
にロードされますか? 記憶のPT_LOAD
どこにある?.tbss
c++ - 別のスレッドからスレッドローカルにアクセスする
別のスレッドからスレッドローカル変数を読み書きするにはどうすればよいですか? つまり、スレッド AI は、スレッド B のスレッド ローカル ストレージ領域にある変数にアクセスしたいと考えています。他のスレッドのIDはわかっています。
変数は__thread
GCC と同様に宣言されます。ターゲット プラットフォームは Linux ですが、独立していると便利かもしれません (ただし、GCC 固有のものは問題ありません)。
スレッド開始フックがないため、各スレッドの開始時にこの値を単純に追跡する方法はありません。すべてのスレッドをこの方法で追跡する必要があります (特別に開始されたスレッドだけではありません)。
boost thread_local_storage や pthread キーの使用などのより高いレベルのラッパーはオプションではありません。真の__thread
ローカル変数を使用するパフォーマンスが必要です。
最初の答えは間違っています: 私がやりたいことにグローバル変数を使用することはできません。各スレッドには、変数の独自のコピーが必要です。さらに、これらの変数は__thread
、パフォーマンス上の理由から変数でなければなりません (同様に効率的なソリューションも問題ありませんが、私は何も知りません)。また、スレッドのエントリ ポイントも制御しないため、これらのスレッドが何らかの構造を登録する可能性はありません。
Thread Local is not private : スレッドローカル変数に関する別の誤解。これらは、スレッドのプライベート変数ではありません。それらはグローバルにアドレス指定可能なメモリであり、その有効期間はスレッドに関連付けられているという制限があります。これらの変数へのポインターが与えられた場合、任意のスレッドの任意の関数が変数を変更できます。上記の質問は、基本的にそのポインターアドレスを取得する方法に関するものです。
c - スレッド ローカル ストレージのオーバーヘッド
グローバル変数を使用する再入不可関数があるとします。
そして、この関数をマルチスレッド コードで使用したいので、次のようにコードを変更できます。
または、gcc __thread 指定子を使用すると、より簡単になります。
最後の利点は、foo() を呼び出す別のコードを変更する必要がないことです。
私の質問は、スレッド ローカル ストレージのオーバーヘッドはどれくらいですか? TLS には明らかではない問題がありますか?
次のように、別のポインターを介して TLS`ed 変数を変更する場合、オーバーヘッドはありますか?
ありがとう。
c# - スレッドローカルストレージへのアクセス
2番目のスレッドが実行されると、例外が発生します。plsは理由を説明できますか?
例外の詳細:
at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
at System.LocalDataStoreMgr.AllocateNamedDataSlot(String name)
at ConsoleApplication2.TLS.Run() in AutoLock.cs:line 65
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
ありがとう。
c++ - スレッドローカルストレージを割り当てる方法は?
関数に静的な変数がありますが、スレッドごとに静的にしたいと考えています。
各スレッドが独自のクラス インスタンスのコピーを持つように、C++ クラスにメモリを割り当てるにはどうすればよいですか?
これはLinux上にあります。私は C++0x を使用していません。これは gcc v3.4.6 です。
multithreading - アセンブリ - スレッド セーフなローカル変数
アセンブリ プログラムでスレッド セーフなローカル変数を使用しようとしています。ネットで検索しましたが、簡単なものは見つかりませんでした。
プログラムはCコードとアセンブリが混在しているため、現在GCCアセンブラを使用していますが、最終的なプログラムには複数のプラットフォーム/呼び出し規約のコードが含まれます。
今のところ、.lcomm
疑似操作を使用して変数を宣言しました。私が理解しているように、これらの変数は.bss
セクションに配置されます。したがって、それらはすべてのスレッドで共有されると思います。
ある種の TLS 変数をアセンブリに直接含める方法はありますか、pthread
または__declspec
Windows などのプラットフォーム固有の実装を使用する必要がありますか?
それが十分に明確であることを願っています。さらに情報が必要な場合は、遠慮なくお尋ねください。
みんなありがとう、
編集
問題のコードは次のとおりです。
基本的に、呼び出しを C 関数にリダイレクトするために使用されます。
C プロトタイプは次のとおりです。
これは、最初の引数として関数ポインターを取るため、callq *%rdi
システム V ABI でこれをテストしているためです。
アセンブリ コードは非常に単純であり、保守しやすいように維持したいと考えています。
問題は、変数stack0
とstack1
変数をスレッドセーフにする方法です。