4

質問1

サーバーの RAM メモリ キャッシュ レイヤーを構築/検索しています。これは、同時要求 (Get と Sets の両方) を処理する必要がある単純な LRU キャッシュです。

https://github.com/pmylund/go-cacheがスレッドセーフであると主張していることがわかりました。

これは、保存されたインターフェイスを取得する限り当てはまります。しかし、複数のゴルーチンが同じデータを要求する場合、それらはすべて、同じメモリ ブロックへのポインター (インターフェースに格納されている) を取得しています。ゴルーチンがデータを変更する場合、これはもはや安全ではありません。

この問題に取り組むキャッシュパッケージはありますか?


質問 1.1

質問 1に対する答えが「いいえ」の場合、推奨される解決策は何ですか?
2 つのオプションが表示されます。

代替案 1の
解決策:sync.Mutex各ゴルーチンがデータの読み取り/書き込みの前にデータをロックする必要があるように、値を a を使用してラッピング構造体に格納します。
type cacheElement struct { value interface{}, lock sync.Mutex }
欠点:キャッシュは、データに加えられた変更を認識しなくなったり、キャッシュから削除されたりすることさえあります。1 つのゴルーチンが他のゴルーチンをロックすることもあります。

代替案 2の
解決策:データのコピーを作成します (データ自体にポインターが含まれていないと仮定します)
。 欠点:キャッシュ Get が実行されるたびにメモリが割り当てられ、ガベージ コレクションが増えます。


マルチパートの質問で申し訳ありません。しかし、すべてに答える必要はありません。質問 1 に適切な答えがあれば、それで十分です。

4

2 に答える 2

3

tux21b は良い答えを出しました。データへのポインターを返す必要がないことを指摘しておきます。非ポインター値をキャッシュに保存すると、コピーになる値で渡されます。キャッシュの内容を実際に変更することはできないため、Get メソッドと Set メソッドは安全になります。

于 2012-07-11T14:20:13.960 に答える