0

データをスレッドセーフにする「最良の」方法は何だろうと思っています。

具体的には、リンクされたリストを複数のスレッドで保護する必要があります。あるスレッドがリンクされたリストから読み取ろうとしているときに、別のスレッドがデータを追加/削除したり、リスト全体を解放したりする可能性があります。ロックについて読んでいます。これらは最も一般的に使用されるアプローチのようですが、明らかに問題 (デッドロック) になる可能性があります。また、アトミック操作とスレッドローカルストレージについても読みました。

あなたの意見では、私の最善の行動方針は何ですか? ほとんどのプログラマーが使用するアプローチは何ですか? また、その理由は何ですか?

4

4 に答える 4

5

頻繁に使用されるわけではありませんが、非常に健全なアプローチの 1 つは、すべての「共有」構造を所有する 1 つの専用スレッドを指定することです。そのスレッドは通常、(スレッドセーフ;-)キューで待機しています。たとえば、PythonQueue.Queueインスタンスでは、作業リクエスト(共有構造の読み取りまたは変更)を待ちます。これには、応答を要求する両方のリクエストが含まれます(独自のキューを準備ができたときに応答が配置されるもの) とそうでないもの。このアプローチは、共有リソースへのすべてのアクセスを完全にシリアライズし、マルチプロセスまたは分散アーキテクチャに簡単に再マップし (Python では ;- を使用してほとんど頭multiprocessingを使わずに)、健全性とデッドロックの欠如、および競合状態を完全に保証します。基礎となるキュー オブジェクトは完全に適切にプログラムされています。

これは基本的に、共有データ構造の地獄をメッセージ パッシング同時実行アーキテクチャの楽園に変えます。

OTOH、それはロックで難しい方法でそれを長引かせるよりもオーバーヘッドが少し高いかもしれません&c;-)。

于 2009-06-15T02:40:17.190 に答える
0

スレッドセーフの最も重要なルールを常に覚えておいてください。コードのすべてのクリティカル セクションを完全に把握します。そしてそれによって、あなたのいろはのようにそれらを知ってください。尋ねられたときにそれらを特定できる場合にのみ、スレッドセーフメカニズムを操作する領域を知ることができます.

その後、経験則を覚えておいてください。

  • ヒープ上のすべてのグローバル変数/変数に注意してください。
  • サブルーチンが再入可能であることを確認してください。
  • 共有データへのアクセスがシリアル化されていることを確認してください。
  • ポインタによる間接アクセスがないことを確認してください。

(他の人がもっと追加できると確信しています。)

于 2009-06-15T02:33:05.927 に答える
0

安全性の観点からの「最善の」方法は、データ構造全体をロックして、一度に 1 つのスレッドだけがアクセスできるようにすることです。

おそらくパフォーマンス上の理由から、構造全体よりも少ない部分をロックすることを決定すると、これを行う詳細は面倒であり、すべてのデータ構造、さらには同じ構造のバリアントごとに異なります。

私の提案は

  1. データ構造のグローバル ロックから始めます。プログラムのプロファイルを作成して、それが本当に問題かどうかを確認してください。

  2. 問題がある場合は、問題を分散する他の方法がないかどうかを検討してください。問題のデータ構造のデータ量を最小限に抑えて、頻繁に、または長時間アクセスする必要がないようにできますか? たとえば、キュ​​ーイング システムの場合、スレッドごとにローカル キューを保持し、ローカル キューの負荷が過負荷または負荷不足になったときにのみ、グローバル キューに物を移動したり、グローバル キューから移動したりできます。

  3. 実行している特定のタイプの競合を減らすのに役立つように設計されたデータ構造を調べ、安全性の面で誤りを犯して慎重かつ正確に実装します。キューイングの例では、ワークスティーリング キューが必要になる場合があります。

于 2009-06-15T02:40:57.483 に答える