マルチスレッドで問題が発生しました。マルチスレッドのモデルは 1 プロデューサー - N コンシューマーです。
Producer はデータ (それぞれ約 200 バイトの文字データ) を生成し、それを固定サイズのキャッシュ (つまり 2Mil) に入れます。データはすべてのスレッドに関連しているわけではありません。フィルター (構成済み) を適用し、生成されたデータに適格なスレッドがないかどうかを判別します。
プロデューサーは、データへのポインターを適格なスレッドのキューにプッシュします (データのコピーを避けるため、データへのポインターのみ)。スレッドはそれをデキューし、TCP/IP 経由でクライアントに送信します。
問題: データへのポインタのみが複数のスレッドに渡されるため、キャッシュがいっぱいになると、プロデュースは最初のアイテム (古いアイテム) を削除したいと考えています。スレッドがまだデータを参照している可能性があります。
実現可能な方法 : アトミック粒度を使用します. プロデューサーが適格なスレッドの数を決定すると, カウンターとスレッド ID のリストを更新できます.
class InUseCounter
{
int m_count;
set<thread_t> m_in_use_threads;
Mutex m_mutex;
Condition m_cond;
public:
// This constructor used by Producer
InUseCounter(int count, set<thread_t> tlist)
{
m_count = count;
m_in_use_threads = tlist;
}
// This function is called by each threads
// When they are done with the data,
// Informing that I no longer use the reference to the data.
void decrement(thread_t tid)
{
Gaurd<Mutex> lock(m_mutex);
--m_count;
m_in_use_threads.erease(tid);
}
int get_count() const { return m_count; }
};
マスターチャッシュ
map<seqnum, Data>
|
v
pair<CharData, InUseCounter>
プロデューサーがカウンターをチェックする要素を削除すると、0 より大きい場合、m_in_use_threads セット内のスレッドへの参照を解放するアクションを送信します。
質問
- マスター キャッシュに 2Mil のレコードがある場合、同じ数の InUseCounter が存在するため、Mutex 変数は、1 つのプロセスで 2Mil のミューテックス変数を持つことをお勧めします。
- InUseCounter を維持するために大きな単一のデータ構造を持つと、検索とデクリメントにより多くのロック時間が発生します
- 参照を見つけるための私のアプローチに代わる最良の方法は何でしょうか。また、ロック時間が非常に短い参照をすべての人が持っています。
アドバイスありがとうございます。