問題タブ [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++ - スレッド アクセス違反例外の後、ローカル ストレージが破損する
スレッド ローカル ストレージにいくつかのデータが格納されています。基本的に、スレッドごとに、TLS に格納されたある種の属性があります。TLS では、カスタム クラス オブジェクト インスタンス CMyAttributes* を配置します。
これは参照カウント属性ホルダーです
例として:
AddRef と Release をオーバーライドしました。このクラスは参照カウントされます。オブジェクトが破棄されるリリースでは、tls.Set(nullptr) を呼び出して TLS をクリアします。
現在直面している問題は、アクセス違反の例外が発生すると、スレッド ローカル ストレージが破損していることです。GetInstance 呼び出しを呼び出すと、TLS にガベージ値があり、pMyAttributes が null ではなく、Addref がクラッシュすることがわかります。
破損の原因を特定できませんでした。この種の問題のデバッグに関する提案。
windows-services - Windows Embedded Compact 7 サービスとスレッド ローカル ストレージ
Windows Embedded Compact 7 (別名 Windows Embedded CE 7) サービスを開発しています。Boost.Logライブラリはログ記録に使用され、場合によってはBoost Thread ライブラリが使用されます。xxx_IOControlサービス メソッドからログ エントリを追加しようとすると、クラッシュします。
調査の結果、クラッシュの理由は、thread.cpp ブースト スレッド ソース ファイルの add_thread_exit_function で NULL ポインターを逆参照していることがわかりました。NULL ポインター自体の最初の理由は、TlsGetValue/TlsSetValue Windows API 関数の不適切な動作である可能性があります。具体的には、次のコードで:
xxx_IOControl 呼び出し内で呼び出された場合、returnedData は NULL ですが、originalData は NULL ではありません。setOk が TRUE で、両方の TlsXXX 関数が ERROR_SUCCESS を返した後に GetLastError() が呼び出されています。同じコードがxxx_Init呼び出し内で呼び出されている間、returnedData は originalData 値と正しく等しく返されます。両方の呼び出し (xxx_Init と xxx_IOControl) で同じ tlsKey が使用され、それらの間にTlsFree呼び出しはありません。
また、おそらく関連している事実がもう 1 つあります。サービスDLLとboost_thread.dllの両方で、xxx_IOControlを呼び出すスレッドに対してDllMain(DLL_THREAD_ATTACH)が呼び出されません。
Windows CE サービス用の特別なスレッド機構はありますか? 誰かに役立つ関連情報はありますか?
.net - .NET ThreadPool スレッドを使用しているときに CallContext.Logical[set/get]Data を使用しても安全ですか?
ThreadPool.QueueUserWorkItemのように使えば、これらのメソッドを使って設定したものであるLogicalCallContextが新しいスレッドに流れることが分かりました。問題は、このオブジェクトを持つスレッドがスレッドプールによって再利用されると、論理呼び出しコンテキストがリセットされるかどうかです。それとも自分のものではない状態になってしまうのでしょうか?
言及のカップル:
- .net ソース コードからわかることから、新しいタスクをスレッド プールにエンキューするたびに、実行コンテキスト全体が複製されます。このコンテキストにはセキュリティ関連のものも含まれているため、コンテキストがリセットされない場合、これは大きな問題になると思います。
- テストアプリでは、使用が終わった後にコンテキストからダミー値に状態を設定しても、再利用時に悪い状態になる可能性を高めるために、正常に動作するようです.
- 私は非同期プログラミング、Windowsフォーム/ WPFなどを使用していません。単純な .NET API 呼び出し (「Begin...」で始まる呼び出しはありません)
- スレッドが切り替わったときにクリアされないため、スレッドローカルストレージを使用するだけでは機能しないことを理解しています。
ありがとう
gcc - gcc / ld: 静的にリンクされた ELF バイナリで重複するセクション (.tbss、.init_array)
gcc バージョン 4.8.2 (Debian 4.8.2-21) を搭載した x86_64 マシン上の Debian 7 システムで、非常に単純な hello-world ワンライナーを静的にコンパイルしています。
そして、次のセクションを含む実行可能な ELF ファイルを取得します。
.tbss
セクションはアドレス 0x6b4020..0x6b4050 (0x30 バイト) に割り当てられ、0x6b4020..0x6b4030 (0x10 バイト) の.init_array
セクションの割り当て、0x6b4030..0x6b4040 (0x10 バイト)の.fini_array
セクション、および 0x6b4040..0x6b4048 のセクションと交差することに注意して.jcr
ください。 (8 バイト)。
次のセクションと交差しない.data.rel.ro
ことに注意してください.data.rel.ro
。
結果のファイルは正常に実行されますが、どのように機能するかはまだ正確にはわかりません。私がglibcのドキュメントで読んだことから、スレッドローカルストレージ.tbss
の単なる.bss
セクションです(つまり、実際には物理ファイルにマップされていない、割り当てられたメモリスクラッチスペース)。その.tbss
セクションは他のセクションと重なるほど特別なセクションですか?.init_array
、.fini_array
および.jcr
は役に立たない (たとえば、TLS 関連のコードが実行されると不要になった) ため、bss によって上書きされる可能性がありますか? それとも何かのバグですか?
基本的に、アプリケーションでアドレス 0x6b4020 を読み取ろうとすると、何を読み書きできるのでしょうか? .tbss
内容または.init_array
ポインタ?なんで?
java - Aspectj クラスの ThreadLocal.remove() をコーディングする場所
/* Aspect を使用して既存のアプリケーションで AOP を実行し、スレッドローカルを使用して GUId を保存しています。@Around アノテーションを使用しています。トランザクションの開始時に、initialValue() メソッドを使用してトランザクションに GUID を設定しています。
問題は、スレッドローカルを使用しているときに知っているように、スレッドローカルからデータを削除することにも注意する必要があることです。そうしないと、メモリ不足の実行が発生する可能性があります。側面の最後でそれを削除すると、コードが破損し、UUID 値が変更されます。
メモリ不足なしでそれを達成する方法を提案してください。
コード :- */
c++ - プログラム終了時に static thread_local std::unique_ptr がクラッシュする
次のようなスレッド ローカル シングルトン クラスがあります。
// UserActionManager.hh
// UserActionManager.cc
プログラムで他のステップが完了した後に UserActionManager を作成する必要があるため、インスタンスに動的割り当てを使用する必要があります。
プログラムを実行すると、プログラムが終了するまで正常に動作します。次のようなエラーが表示されます。
このプログラムを lldb で実行すると、このメッセージが表示されます。これは、thread_local UserActionManager インスタンスのデフォルトの削除呼び出しでクラッシュが発生していることを示しています。
// lldb 出力
ただし、スレッド ローカル インスタンスのコードによって出力されたポインターと、割り当てられずに解放されているポインターを見ると、それらは同じではありません。
// GetUserActionManager() によって出力されるポインター:
// クラッシュの原因となるポインター:
ここで何が起こっているのですか?過去にこのコードを問題なく使用しました。現在、MacOSX および c++14 で g++ 4.9.1 を使用しており、このクラッシュが発生しています。UserActionManager のデストラクタが呼び出されることはなく、デフォルトの削除が解放しようとしているポインタが本来あるべきものとは異なります。私はコードをgrepしましたが、これはインスタンスへの参照のみであり、それを作成する静的メソッドにあるため、これは他の場所からの副作用ではないと思います. theInstance に生のポインターを使用すると、コードは正常に機能します。
この問題を解決する方法について何か提案はありますか? ありがとう!
編集:
私はこれを見つけました:
プログラムの終了時にグローバルまたは静的オブジェクトがクラッシュする可能性があるのはなぜですか?
UserActionManager は現在ライブラリの一部であり、プログラム「シンプル」がそれにリンクしています。以前 (これが機能していたとき)、コードをすべて 1 つのピースとしてコンパイルしていました。これが問題の原因になっている可能性はありますか?」
c++ - ページ テーブル マッピングでスレッド ローカル ストレージが実装されないのはなぜですか?
thread_local
非常に頻繁にアクセスされるスレッドごとのブール値フラグにC++11 キーワードを使用したいと考えていました。
ただし、ほとんどのコンパイラは、整数 ID (スロット) を現在のスレッドの変数のアドレスにマップするテーブルを使用して、スレッド ローカル ストレージを実装しているようです。このルックアップは、パフォーマンスが重要なコード パス内で発生するため、そのパフォーマンスについて懸念があります。
スレッド ローカル ストレージが実装されることを期待していた方法は、スレッドに応じて異なる物理ページによってサポートされる仮想メモリ範囲を割り当てることです。そうすれば、フラグへのアクセスは、MMU がマッピングを処理するため、他のメモリ アクセスと同じコストになります。
主流のコンパイラのどれも、このようにページ テーブル マッピングを利用しないのはなぜですか?
mmap
Linux とVirtualAlloc
Win32 で独自の「スレッド固有のページ」を実装できると思いますが、これはかなり一般的な使用例のようです。誰かが既存の解決策またはより良い解決策を知っている場合は、それらを教えてください。
std::atomic<std::thread::id>
また、アクティブなスレッドを表すために各オブジェクト内に を格納することも検討しましたが、プロファイルを作成すると、チェックstd::this_thread::get_id() == active_thread
が非常に高価であることがわかります。
c++ - c++11 グローバル初期化順序と thread_local
こんにちは、gcc 4.8.1 を使用して以下を実行すると、thread_local キーワードを使用してアサーションがヒットします。thread_local を削除すると、アサートはヒットしません。これがなぜなのか誰か知っていますか?未定義のグローバル順序がいくつかありますが、ptr_ を割り当てる前に buf_ が有効なアドレスを持つことを期待します。キーワード thread_local を削除するだけでうまくいきます。
出力:
Test.hpp
main.cpp
c++ - thread_local が gcc 4.9.1 の下の Mac OSX 10.7.2 で壊れているようです
ここに来るのは初めてです... マルチスレッドの C++ コードを使用しようとしています。私は Mac OSX 10.7.2 を使用しています。OS とコンパイラが古く、c++11 をサポートしていないため、こちらの指示に従いまし たhttps://solarianprogrammer.com/2013/06/11/compiling-gcc-mac-os-x/ gcc 4.9.1が動作していますが、マルチスレッドを試してみました。
さて、これを次のようにコンパイルすると
次のようなエラーが表示されます。
a.out(50392,0x100605000) malloc: * オブジェクト 0x137fe130400db0 のエラー: 解放中のポインターが割り当てられていません * malloc_error_break にブレークポイントを設定して、不正な命令をデバッグします: 4
a.out(50405,0x102a70000) malloc: * オブジェクト 0x137fcf22500060 のエラー: 解放中のポインターが割り当てられていません * malloc_error_break にブレークポイントを設定して、不正な命令をデバッグします: 4
コマンドライン オプションとして -pthread と -lpthread を追加しようとしましたが、役に立ちませんでした。print ステートメントも追加しました。これにより、エラー メッセージ内のアドレスが静的ローカル オブジェクト自体のアドレスであることが明らかになりました。
あまりにも時代遅れの環境でこれを実行しようとしているのかもしれません。または、適切なランタイムがリンクされていない可能性があります。誰かが助けてくれるかどうかはわかりません...おそらく、より最新のシステムにアクセスする必要があるだけかもしれません。
ありがとう!!
c++ - アクション リスト 9.9(msvc 12.0) での C++ 同時実行の問題をコンパイルします。
これを msvc 12.0 でコンパイルしようとしています。本のコードはキーワード thread_local を使用していますが、msvc 12.0 はこれをサポートしていないようです。thread_local を使用する代わりに __declspec(thread) を試しましたが、次のコンパイラ エラーが発生しました。
これが私のコードです:
};
msvc 12.0 でこれに対する回避策はありますか?