タグ付けされた質問 「thread-safety」

複数のスレッドによるこのコードの一貫した実行を可能にする方法でのみデータ構造を操作する場合、コードの一部はスレッドセーフです。コードは、スレッドセーフ、条件付きで安全(相互排除が必要)、または安全ではない(1つのスレッドだけが安全に使用できる)場合があります。

3
スレッドセーフvsリエントラント
最近、「mallocスレッドは安全ですか?」というタイトルで質問しました。、そしてその中で私は「mallocはリエントラントですか?」と尋ねました。 私は、すべての再入可能性がスレッドセーフであるという印象を受けました。 この仮定は間違っていますか?

3
lock(new object())—カーゴカルトまたはクレイジーな「言語の特殊なケース」?
コンサルタントによって作成されたコードを確認しています。すでに数十の危険信号が表示されていますが、次のスニペットに頭を悩ませることはできません。 private void foo() { if (InvokeRequired) { lock (new object()) { if (m_bar!= null) Invoke(new fooDelegate(foo), new object[] { }); } } else { if(OnBazChanged != null) OnBazChanged(); } } ここでlock(new object())は何をしていますか?常に別のオブジェクトをロックしているため、何の効果もありませんが、この種のロックは、コピーして貼り付けられていない部分であっても、コード全体で持続します。これは、私が知らないものにコンパイルされたC#言語の特殊なケースですか、それともプログラマーは、たまたま機能していたカーゴカルトを採用しただけですか?


4
レールでのThread.current []の使用の安全性
情報をThread.currentハッシュに格納する方法(たとえば、current_user、現在のサブドメインなど)について、相反する意見が寄せられています。この手法は、モデルレイヤー内でのその後の処理(クエリスコープ、監査など)を簡素化する方法として提案されています。 Railsでスレッド変数が断続的になるのはなぜですか? RailsのAPIラッパーでThread.currentを使用する代わりに Thread.current []値とクラスレベル属性はRailsで安全に使用できますか? 多くの人は、MVCパターンを壊すため、このプラクティスは受け入れられないと考えています。他の人はアプローチの信頼性/安全性について懸念を表明し、私の2部構成の質問は後者の側面に焦点を当てています。 Thread.currentハッシュは、そのサイクル全体を通じて、1つの応答に対してのみ使用可能でプライベートであることが保証されていますか? 応答の最後にスレッドが他の着信要求に引き渡され、それによってに格納されてThread.currentいる情報が漏洩する可能性があることを理解しています。応答が終了する前に(たとえばThread.current[:user] = nil、コントローラーから実行することによって)そのような情報をクリアすることは、after_filterそのようなセキュリティ違反を防ぐのに十分でしょうか? ありがとう!ジュゼッペ


3
マルチスレッド化プログラムは最適化モードのままですが、-O0で正常に実行されます
簡単なマルチスレッドプログラムを次のように記述しました。 static bool finished = false; int func() { size_t i = 0; while (!finished) ++i; return i; } int main() { auto result=std::async(std::launch::async, func); std::this_thread::sleep_for(std::chrono::seconds(1)); finished=true; std::cout<<"result ="<<result.get(); std::cout<<"\nmain thread id="<<std::this_thread::get_id()<<std::endl; } それはでデバッグモードで正常に動作するVisual Studioのか-O0にGC Cとした後、結果をプリントアウト1秒。しかし、スタックモードになり、リリースモードまたはで何も印刷しません-O1 -O2 -O3。

3
「揮発性」は、マルチコアシステムのポータブルCコードで何かを保証しますか?
見た後、束 の 他の 質問 と その 回答を、私はという印象を得るCで「揮発性」というキーワードが正確に何を意味するのかには広範な合意はありませんが。 標準自体でさえ、誰もがそれが何を意味するのかについて合意するのに十分明確ではないようです。 他の問題の中で: それはあなたのハードウェアとあなたのコンパイラに依存して異なる保証を提供するようです。 コンパイラの最適化には影響しますが、ハードウェアの最適化には影響しません。そのため、独自のランタイム最適化を行う高度なプロセッサでは、コンパイラが防止したい最適化を防止できるかどうかさえ明確ではありません。(一部のコンパイラーは、一部のシステムで一部のハードウェア最適化を防止するために命令を生成しますが、これは決して標準化されていないようです。) 問題を要約すると、「大量に読み取った後」「揮発性」が次のようなことを保証しているように見えます。値は、レジスタからだけでなく、少なくともコアのL1キャッシュにも、同じ順序で読み書きされます。読み取り/書き込みがコードに表示されます。しかし、これは役に立たないようです。レジスタからの読み取り/レジスタへの書き込みは同じスレッド内ですでに十分ですが、L1キャッシュとの調整は、他のスレッドとの調整に関してそれ以上何も保証しません。L1キャッシュとだけ同期することがいつ重要になるかは想像できません。 USE 1 揮発性の広く合意された使用は、ライトを(直接、ハードウェアで)制御するメモリ内のビットのように、特定のメモリ位置がI / O機能にハードウェアでマッピングされている古いシステムまたは組み込みシステムであるようです、またはキーボードのキーが押されているかどうかを通知するメモリ内のビット(ハードウェアによって直接キーに接続されているため)。 と思われる「利用1」とは、そのターゲットのマルチコアシステムを含んポータブルなコードでは発生しません。 USE 2 「use 1」とそれほど変わらないのは、割り込みハンドラー(ライトの制御やキーからの情報の保存など)によっていつでも読み書きできるメモリです。しかし、すでにこのため、システムによっては、割り込みハンドラが 独自のメモリキャッシュを備えた別のコアで実行される可能性があり、「揮発性」はすべてのシステムでキャッシュの一貫性を保証しないという問題があります。 したがって、「use 2」は「volatile」が提供できる範囲を超えているようです。 USE 3 他に議論の余地のない唯一の用途は、コンパイラーが認識しない同じメモリーを指している同じメモリーを指すさまざまな変数を介したアクセスの誤最適化を防ぐことです。しかし、人々がそれについて話していないので、これはおそらく議論の余地がないだけです-私はそれについての言及を1つだけ見ました。また、C標準では、「異なる」ポインター(関数への異なる引数など)が同じ項目または近くの項目を指す可能性があることをすでに認識しており、コンパイラーがそのような場合でも機能するコードを生成する必要があることをすでに指定しています。しかし、私はこのトピックを最新(500ページ)の標準ですぐに見つけることができませんでした。 では「use 3」はまったく存在しないのでしょうか。 したがって、私の質問: 「揮発性」は、マルチコアシステムのポータブルCコードで何かを保証しますか? 編集-更新 最新の標準を参照した後、答えは少なくとも非常に制限されているように見えます: 1.標準は、特定のタイプ "volatile sig_atomic_t"の特別な扱いを繰り返し指定しています。ただし、この規格では、マルチスレッドプログラムでシグナル関数を使用すると、未定義の動作が発生することも規定されています。したがって、この使用例は、シングルスレッドプログラムとそのシグナルハンドラ間の通信に限定されているようです。 2.この規格では、setjmp / longjmpに関連する「揮発性」の明確な意味も規定されています。(重要なコードの例は、他の質問と回答に記載されています。) したがって、より正確な質問は次のようになります 。「揮発性」は、(1)シングルスレッドプログラムがシグナルハンドラから情報を受信できるようにする、または(2)setjmpを許可することを除いて、マルチコアシステムのポータブルCコードで何でも保証しますかsetjmpとlongjmpの間で変更された変数を表示するコード? これははい/いいえの質問です。 「はい」の場合、「揮発性」が省略された場合にバグになるバグのないポータブルコードの例を示すことができればすばらしいでしょう。「いいえ」の場合、マルチコアターゲットの場合、これら2つの非常に特殊なケース以外では、コンパイラーは「揮発性」を無視してもかまいません。

2
スレッドセーフルールによって提案された非const引数を使用してコンストラクターをコピーしますか?
レガシーコードの一部のラッパーがあります。 class A{ L* impl_; // the legacy object has to be in the heap, could be also unique_ptr A(A const&) = delete; L* duplicate(){L* ret; legacy_duplicate(impl_, &L); return ret;} ... // proper resource management here }; このレガシーコードでは、オブジェクトを「複製」する関数はスレッドセーフではない(同じ最初の引数を呼び出す場合)ためconst、ラッパーでマークされていません。私は現代のルールに従っていると思います:https : //herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/ これduplicateは、そうではない詳細を除いて、コピーコンストラクタを実装する良い方法のように見えconstます。したがって、これを直接行うことはできません。 class A{ L* impl_; // the legacy object has …

2
forループで配列を反復処理することは、C#のスレッドセーフ操作ですか?IEnumerable <T>をforeachループで反復するのはどうですか?
私の理解に基づいて、C#の配列を指定して、複数のスレッドから同時に配列を反復処理の行為は、あるスレッド安全な操作。 することにより、配列を反復処理 Iは、によって、アレイ内のすべての位置を読んで意味昔ながらのforループ。各スレッドは単に配列内のメモリ位置のコンテンツを読み取っているだけで、誰も何も書き込んでいないため、すべてのスレッドが一貫した方法で同じものを読み取ります。 これは、上で書いたことを実行するコードの一部です。 public class UselessService { private static readonly string[] Names = new [] { "bob", "alice" }; public List&lt;int&gt; DoSomethingUseless() { var temp = new List&lt;int&gt;(); for (int i = 0; i &lt; Names.Length; i++) { temp.Add(Names[i].Length * 2); } return temp; } } したがって、私の理解では、メソッドDoSomethingUseless はスレッドセーフでありstring[]、をスレッドセーフタイプ(ImmutableArray&lt;string&gt;たとえば)に置き換える必要はありません。 私は正しいですか? …

2
非同期コード、シェア変数、スレッドプールスレッド、スレッドセーフ
async / awaitを使用して非同期コードを作成するとき、通常ConfigureAwait(false)はコンテキストのキャプチャを回避するために、コードがスレッドプールスレッドから次のスレッドプールスレッドにジャンプしていawaitます。これにより、スレッドの安全性に関する懸念が生じます。このコードは安全ですか? static async Task Main() { int count = 0; for (int i = 0; i &lt; 1_000_000; i++) { Interlocked.Increment(ref count); await Task.Yield(); } Console.WriteLine(count == 1_000_000 ? "OK" : "Error"); } 変数iは保護されておらず、複数のスレッドプールスレッド*によってアクセスされます。アクセスのパターンは非並行ですが、理論的には各スレッドがローカルにキャッシュされた値をインクリメントiして、1,000,000回を超える反復が可能になるはずです。しかし、実際にはこのシナリオを作成することはできません。上記のコードは、私のマシンでは常にOKを印刷します。これは、コードがスレッドセーフであることを意味しますか?またはi、lock?を使用して変数へのアクセスを同期する必要があります。 (*私のテストによれば、スレッドの切り替えは平均して2回の反復ごとに発生します)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.