2

複雑なデータ構造をメモリ(キャッシュデータ)に保持するマルチスレッドC++アプリケーションがあります。

データを読んでいる間は、すべてが素晴らしいです。データにアクセスしたい数のスレッドを持つことができます。

ただし、キャッシュされた構造は静的ではありません。

  • 要求されたデータ項目が利用できない場合は、データベースから読み取られ、データツリーに挿入されます。これもおそらく問題ではなく、新しいデータ項目をツリーに追加するときにミューテックスを使用しても、数サイクルしかかかりません(ポインターを追加するだけです)。
  • 時々実行されるガベージコレクションプロセスがあります。ツリーからすべての古いアイテムを削除します。そのためには、メモリから削除されるデータに他のプロセスが現在アクセスしていないことを確認するために、すべてをロックダウンする必要があります。また、キャッシュから読み取る間はツリーをロックして、処理中にアイテムを削除しないようにする必要があります(「逆の場合も同じ」のようなものです)。

「擬似コード」:

function getItem(key)
   lockMutex()
   foundItem = walkTreeToFindItem(key)
   copyItem(foundItem, safeCopy)
   unlockMutex()
   return safeCopy
end function

function garbageCollection()
   while item = nextItemInTree
      if (tooOld) then
         lockMutex()
         deleteItem(item)
         unlockMutex()
      end if
   end while
end function

気になること:これは、読んでいる間はツリーをロックする必要があることを意味します(読んでいる間にガベージコレクションが開始されないようにするため)。ただし、副作用として、2つの読み取りプロセスを同時に実行することもできなくなりました。

助言がありますか?

「これは書き込みとのみ衝突する読み取り専用アクション」Mutexのようなものはありますか?

4

4 に答える 4

11

読み取り/書き込み-ロックを調べます

使用できるフレームワークを指定しませんでしたが、pThreadboostの両方がそのパターンを実装しています。

于 2009-10-21T16:26:13.537 に答える
4

コンセプトは、他の人が述べているように、「共有リーダー、シングルライター」ロックです。pthread_rwlock_tLinux環境では、フレームワークなしで使用できるはずです。私も調べることをお勧めしboost::shared_lockます。

于 2009-10-21T16:32:35.813 に答える
3

リーダーライターロックをお勧めします。アイデアは、「読み取り」または「書き込み」用のロックを取得でき、ロックは複数のリーダーを許可しますが、ライターは1つだけです。とても便利な。

于 2009-10-21T16:26:40.790 に答える
0

C ++ 17では、このタイプのアクセス(複数の読み取り、単一の書き込み)は、std::shared_mutexで直接サポートされます。これはboost::shared_lockから採用されたと思います。このトピックは、AnthonyWilliamsのC++ ConcurrencyinActionの例でも説明されています。 https://livebook.manning.com/book/c-plus-plus-concurrency-in-action-second-edition/chapter-3/185

重要なビットは次のとおりです。

  • 共有アクセスが許可されている読み取りでは、std::shared_lockを使用します
    • 既存のshared_locksは、新しいshared_lockのロックを妨げません
  • 排他的アクセスが必要な更新/書き込み関数でstd::unique_lockを使用する
    • 既存のすべての共有読み取りと他の書き込みが完了するまで待機します
    • ロックされている間、他の読み取りまたは書き込みを排除します
于 2019-11-30T14:36:48.680 に答える