問題タブ [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.

0 投票する
3 に答える
8764 参照

c++ - CWnd :: GetSafeHwnd()とCWnd :: m_hWndはスレッドセーフですか?

非常にマルチスレッド化されているアプリケーションで多数のクラッシュに直面しています。

これらのMSDNページテクニカルノート、およびTLSに関するこの記事を読んでCWnd、オブジェクトがスレッドローカルストーガ(スレッド依存のメモリアクセスであるTLS)のHWNDにマップされていることを理解しました。

HWNDCWndスレッドリモートアクセスのように見えるものをすべて分離し、それを参照に変換して::PostMessage、通信ポートとして使用するつもりでした。

しかし、私の同僚の1人は、私が外国人のスレッドにとどまり、ポリシーCWnd*を採用しても大丈夫だと本当に主張しましたが、ネイティブを回復するために外国人のスレッドでまたはを使用します。::PostMessageCWnd::GetSafeHwnd()pMyCWnd->m_hWndHWND

私は、がスレッドセーフであることをどこにも見たことがなく、オブジェクトがTLSにあるため、別のスレッドでの値が異なると主張してきました。GetSafeHwnd()CWnd

私は間違っていますか?MSDNは明らかに予期しない結果という用語を使用しています。

作成者スレッドからの呼び出しCWnd::GetSafehwnd()または外部スレッドについて、あなたの見解は何ですか?pMyCWnd->m_hWnd

これが安全かどうかを示すMSDNドキュメントはありますか。

0 投票する
1 に答える
3636 参照

c++ - 動的にロードされたDLLに(C ++)スレッドローカルストレージを適切に実装するにはどうすればよいですか?

この場合、動的にロードされたDLLは、ファイル/フォルダーのプロパティページに新しいプロパティシート(新しいタブ)を追加するために、Windowsエクスプローラーによってロードされます。

この簡単な例は、StrmExt.dll(ダウンロードソース)です。この例(Microsoftが提供するソース)では、DLLはスレッドローカルストレージ(TLS)を使用しないため、複数のプロパティページを同時にロードするときに大きな問題が発生します。

ソースを確認すると、DLLには1つのスレッドベース変数(ファイルのファイルパス)が必要でした...

この1行のコードを次のように変更します。

... DLLが複数のスレッドをサポートできるようにしたため、プロパティシートの複数のインスタンスをサポートできるようになりました。ただし、この変更はWindows Vista以降でのみサポートされることを私は知っていました(Windows 7でのテストは非常に肯定的です)。たとえば、XPは、動的にロードされたライブラリではこれをサポートしません...そしてアプリケーションをクラッシュさせることが知られています。(最後の段落を参照)。

XPで実行するために、この宣言を使用できませんでした。DLLエントリポイントを次の場所から拡張する必要があると思いました。

...このようなものに...以前にここで見たように

これは、1つまたは2つのスレッドを作成するかどうかに関係なく、DLLの最初のロード中に正常に機能します。DLLが解放された後、ライブラリの次のロード時にExplorerがクラッシュします。

私は何を誤解していますか?元の開発者がDLLプロセスの接続通知時にスレッド通知を意図的に無効にしていることに気付きました。なんで?

0 投票する
3 に答える
9658 参照

java - インスタンス変数での ThreadLocal の使用

Java 変数がインスタンス変数として使用された場合 (たとえば、スレッド ローカル オブジェクトを生成するメソッドで)、 JavaThreadLocal変数はスレッド ローカル値を生成しますか?それとも、そのためには常に静的でなければなりませんか?

例として、スレッドセーフではないクラスの初期化にコストがかかるいくつかのオブジェクトを、単一の静的初期化ブロックでインスタンス化し、単一のクラスの静的変数 (たとえば、Mapデータそれ以降、多数の異なるスレッドによる集中的な処理に使用されます。

スレッド セーフを実現するには、明らかに各静的オブジェクトの異なるコピーを渡す必要があります。たとえば、DateFormat異なるスレッド間で安全に使用する必要がある Java オブジェクトです。

Web で見つけることができる多くの例では、アプローチは各ThreadLocal変数を個別に宣言し、メソッドで新しいオブジェクトをインスタンス化し、メソッドをinitialValue()使用get()してスレッドローカル インスタンスを取得しているようです。

この方法は、作成するオブジェクトが数十または数百あり、それぞれに独自の初期化パラメータがある場合、あまり効率的ではありません。たとえば、SimpleDateFormatそれぞれ異なる日付パターンを持つ多くのオブジェクト。

オブジェクトのインスタンス化が、反復ごとに異なる値を生成するループで実行できる場合、対応するオブジェクトを適切に初期化することによって各値が作成された後に、スレッドローカル インスタンスを生成するための汎用メソッドが必要になります。

上記に基づいて、initialValue() へのすべての呼び出しで同じ参照が生成されるため、次の一般的な静的メソッドは機能しません。

代わりに、initialValue() 内で新しいオブジェクトを作成するメカニズムが必要です。したがって、唯一の一般的なアプローチは、おそらく次のようなパターンでリフレクションを使用することです

次に、もちろん、型固有のオプションがありThreadLocal、ループ内でパターンを使用して各変数を宣言することができます。

たとえば、 の場合DateFormat、単一の静的初期化ブロックで次のことができます。

それ以降、マップは、マップに格納されている1 つ以上のオブジェクトのorメソッドformatsを呼び出すために、毎回異なるスレッドを介して異なるクラスによって読み取られます。format()parse()DateFormat

上記のアプローチのいずれかが説明されている場合に意味がありますか、またはThreadLocal宣言を静的にする必要がありますか?

0 投票する
3 に答える
3251 参照

windows - カーネルモードでのスレッドローカルストレージ?

Windows (正確には Win32) のカーネル モード ドライバーに相当するスレッド ローカル ストレージ (TLS) はありますか?

私が達成しようとしていること:

最終的に、ドライバーのディスパッチ ルーチン内から、他の多くの関数を呼び出す可能性があります (コールスタックが深い可能性があります)。処理中のリクエストに固有のコンテキスト情報を提供したいと考えています。つまり、すべての関数にパラメーターとして明示的に渡すことなく、呼び出されたすべての関数で表示されるはずの構造体、ポインターがあります。

静的/グローバルの使用は完璧なオプションではありません (マルチスレッド、同期オブジェクトなど)。

それがユーザーモードのコードである場合、そのような状況では明らかに TLS を使用します。TlsGetValueしかし、私の知る限り、 /のようなカーネルモード関数はありませんTlsSetValue。そして、これは理にかなっています-これらの機能が機能するには、最初にプロセス全体のTLSインデックスを割り当てる必要があります. OTOH ドライバー コードは、特定のプロセスに限定されず、任意のスレッドで呼び出すことができます。

ただし、永続的なスレッド固有のストレージは実際には必要ありません。トップレベルの関数呼び出し用にスレッド固有のストレージが必要なだけです。

ハックな方法ではありますが、TLSを「実装」する方法を知っていると思います。TLS インデックスを割り当てる代わりに、常に定義済みのインデックス (index=0 など) を使用します。最上位関数で、保存されている TLS 値を保存し、必要な値で上書きします。完了すると、保存された値が復元されます。

幸いなことに、私は TLS が Win32 でどのように実装されているかを知っています。TIBスレッドごとに構造体 (スレッド情報ブロック) があります。すべてのスレッドで、FS:[18h]セレクターを使用してアクセスできます。にはTIB、(とりわけ) TLS で使用される配列が含まれています。残りは非常に簡単です。

ただし、公式の API を使用して同様のことを実現したいと思います。

  • 必要なものを実現するための公式のカーネルモード API はありますか?
  • 私がやろうとしていることを避ける理由はありますか?再入に問題がある可能性があることはわかっています (つまり、一部のコードが私を呼び出し、TLS 値を上書きしてから、TLS に依存している可能性のある元のコードを最終的に呼び出します)。しかし、これは私の特定のケースでは不可能ですか?
  • これを解決するための汚れの少ない方法はありますか?

前もって感謝します。

PS One は、理論的には SEH を使用する可能性があります (これには、スレッドごとの情報も格納されます)。つまり、最上位のコードを でラップし__try/__except、コンテキスト情報が必要な場所で、いくつかのパラメーターを使用して継続可能な例外を発生させ、__exceptブロック内でパラメーターにコンテキスト情報を入力してから、実行を再開します。これは、文書化されていない機能を使用しない、100% 有効なプログラム フローです。しかし、パフォーマンスの複雑さは言うまでもなく、これは私にとって醜いハックのようです。

0 投票する
1 に答える
1729 参照

tbb - TBB スレッド ローカル ストレージについて

TBBの列挙可能なスレッド固有を理解するのに苦労しています。TLSをテストするためにこの小さなコードを書きました

しかし、出力は厄介です。時々:

そして時には:

その変化はなぜ起こるのでしょうか?また、TBB フォーラムで、TLS に予期される値のすべてが含まれていない場合があることを読みましたが、その理由は明らかに親タスクと子タスクの関係にあります。しかし、それはあまりにも理解していませんでした。

何か助けはありますか?

ありがとうございました。

0 投票する
3 に答える
1429 参照

c - ml64.exe (MSVC 64 ビット X64 アセンブラー) からスレッド ローカル ストレージにアクセスするにはどうすればよいですか?

次の C 関数は、スレッド ローカル ストレージ変数を使用して、スレッド セーフな方法でマルチコア コードの再帰を防止しようとします。ただし、やや複雑な理由により、この関数を X64 アセンブラー (Intel X86 / AMD 64 ビット) で記述し、VC2010 の ml64.exe でアセンブルする必要がありますグローバル変数を使用している場合にこれを行う方法は知っていますが、__declspec(thread) を持つ TLS 変数で適切に行う方法がわかりません。

注: これは、VC2010 が機能のためにキックアウトするものです。gs:88ただし、MASM (ml64.exe) は、またはOFFSET FLAT:コードの一部をサポートしていません。

0 投票する
1 に答える
968 参照

.net - 同じ操作に別のスレッドを使用する場合、WCF は Trace.CorrelationManager のプロパティを伝達しません。

同じ操作に別のスレッドを使用するときに、WCF に Trace.CorrelationManager のプロパティを伝達させるにはどうすればよいですか?

WCF がスレッド アフィニティを保証しないことはわかっています。したがって、基本的に 1 つのスレッドが要求を開始し、別のスレッドがそれを終了することができます。この動作を再現すると、最初のスレッドに Trace.Correlation.ActivityId と Trace.Correlation.LogicalOperationStack の 2 つのプロパティが正しく設定されていることがわかります。WCF は別のスレッドで操作を終了しましたが、プロパティは伝達されませんでした。

これを回避するには、CorrelationManager の使用を放棄する必要があり、おそらく新しいスレッドに伝達されることがわかっている OperationContext に ActivityId を格納する必要があります (ここで間違っている場合は修正してください)。もちろん、より多くの作業が必要であり、その単一のプロパティを使用するほどエレガントではないため、これを行いたくありません。

これを回避する方法について他のアイデアはありますか? どういうわけかこれを伝播するように WCF に指示できますか?

ありがとう、モハメッド

0 投票する
1 に答える
2314 参照

wcf - OperationContext.Current を WCF サービス インスタンスのインスタンス変数に格納する

OperationContext.Current オブジェクトを WCF サービス ホスト インスタンスのインスタンス変数に格納して参照することが賢明かどうかを知りたいと思いました。サービス ホストは InstanceContextMode.PerCall に設定されているため、すべての新しいリクエストは独自のインスタンスを取得します。

これを尋ねる理由は、WCF がスレッド アフィニティを保証しないためです。場合によっては、WCF が 1 つのスレッドで要求を開始し、別のスレッドで要求を終了することがあります。

OperationContext.Current オブジェクトは Thread Local Storage に格納されます。同じ操作に新しいスレッドが使用されると、WCF は新しいスレッドに "伝達" されます。

この場合、WCF が別のスレッドの使用を開始した場合、サービス インスタンスのインスタンス変数に格納された OperationContext オブジェクトにアクセスしても安全ですか?

0 投票する
1 に答える
779 参照

gwt - GWT のローカル リクエスト コンテキスト

Java には、メソッド引数として明示的に渡すことなく、あるオブジェクトから別のオブジェクトにデータを運ぶために使用できる ThreadLocal があります。

GWT リクエストをインターセプトし、そこからカスタム HTTP ヘッダーを抽出する必要があります。次に、ヘッダー値を何らかの方法で保存して、後で処理する必要があります。

問題は、ヘッダーを抽出する場所が RequestBuilder に属し、RequestBuilder 内からサーバーからの要求/応答を実際に処理するカスタム コードに変数を渡す方法 (?) がないことです。また、クライアント コードからそのリクエスト ビルダーに変数を渡すことはできません。

ThreadLocal が解決策になる可能性がありますが、GWT では使用できません。使えるものはありますか?

0 投票する
1 に答える
1343 参照

c# - StructureMap LifeCycleIs new ThreadLocalStorageLifeCycle はスレッド ローカルではありませんか?

StructureMap を使用して、同じタイプの 2 つのインスタンスを 2 つの異なるスレッドに格納しようとしています。各スレッドには独自のインスタンスが必要です。

ただし、上記のテストは失敗します。また、LifecycleIs(new ThreadLocalStorage()) 構成を使用すると、ConfigureThreadLocalStorageTest1 の ObjectFactory.GetInstance() メソッドが null を返すと思いますか?