2

多くのフィールドを持つデータ構造があるとします。スレッドを使用して並行してアクセスしたい。とにかく、構造体全体をロックしたくありません (たとえば、大きなミューテックスを使用して完全に排他的にアクセスする) が、他のスレッドが OTHER フィールドにアクセスしている場合でも、スレッドがフィールドにアクセスできるようにしたいと考えています。出来ますか?はいの場合、どのように?

4

3 に答える 3

1

Java にはConcurrentSkipListMapと ConcurrenSkipListSet があり、このような状況で非常にうまく機能します。また、マルチスレッド環境ではそれほど高速ではありませんが、スレッドセーフな ConcurrentHashMap もあります。同様のものがほとんどの言語で利用できると思います。スキップ リストのアイデア (ディクショナリ/マップのように機能し、ロックではなくコンペアアンドスワップを使用する単一リンク リスト) はかなり新しいものですが、独自のロックを行うハッシュ テーブルはずっと存在しています。(Java を使用しておらず、何かが見つからない場合は、Java はオープン ソースであるため、コードを翻訳して独自のものを作成できます。)

于 2012-06-14T20:32:13.107 に答える
0

簡単な方法は、メモリオーバーヘッドに余裕があると仮定して、各フィールドを保護する個別のミューテックスを用意することです。

編集:ハッシュテーブルについて話しているので、各スロットをロックするとオーバーヘッドが大きくなりすぎますが、単一のロックは非効率的です。

最も受け入れられる方法は、ロックストライピング手法です。これは、K個のロックを維持し、それぞれがM/Kスロットを保護することを意味します(Mはスロットの総数です)。次に、いくつかのベンチマークを実行し、Kを調整して最適なパフォーマンスを得ることができます。

于 2012-06-14T14:52:30.040 に答える
0

ロックの大きな山を持つ代わりに、ハッシュテーブル全体に対して1つしか持つことができませんが、テーブル内の各要素にフラグを使用します。フラグは、要素が現在他の誰かによって使用されていること、およびそれを使用したい人は少し待つ必要があることを示します。したがって、テーブルから要素を取得するには、単一のロックを実行しますが、要素を取得したらすぐに解放します。その後、要素の使用が許可されているかどうかを確認します。そうでない場合は、少し待ってからもう一度確認してください。

ハッシュテーブルから要素を削除できる場合は、各要素の参照カウントが必要です。これにより、参照カウントがゼロになった場合にのみ、要素を削除してテーブルから削除できます。

新しい要素がテーブルに追加されると、テーブルのロック内で追加されます。ロックは要素の削除にも使用されます。うまくいけば、既存の要素へのアクセスは、新しい要素を作成して既存の要素を削除するよりも頻繁に行われます。

于 2012-06-14T15:16:36.690 に答える