共有優先度キュークラスを作成しました。
データの配信を停止するように通知するには、done
という記号を設定し、アプリケーションがキューからデータを読み書きすることを許可しないメソッドCancel()
を使用します。 std::mutex
とstd::condition_variable
と組み合わせてstd::atomic<bool>
を使用することについてはわかりません。私の解決策が安全か、レース状態が発生する可能性がスレッドであるかどうかは、わからない:std :: atomicを使用した正確性<bool>とstd :: mutexの組み合わせ
Enqueue
方法のオリジナルバージョンは次のとおりです。
std::deque<T> deque;
std::mutex mtx;
std::condition_variable cv;
std::atomic<bool> done;
SharedPriorityQueue() : done(false)
{
}
~SharedPriorityQueue()
{
Cancel();
}
void Enqueue(T item)
{
if (done)
{
return;
}
std::lock_guard<std::mutex> lock(mtx);
deque.push_back(item);
cv.notify_one();
}
しかし、変数done
(アトミックブール値)することができから分離mutexによるロック機構?
void Cancel()
{
if (done)
{
return;
}
done = true;
cv.notify_all();
}
怒鳴るデザインの最良の解決策は何ですか?私はこの構造を使用するキューをキャンセルする
// A)
void Enqueue(T item)
{
if (done)
{
return;
}
{
std::lock_guard<std::mutex> lock(mtx); // lock is released before notify call
deque.push_back(item);
}
cv.notify_one();
}
// B)
void Enqueue(T item)
{
{
std::lock_guard<std::mutex> lock(mtx); // done is atomic bool and protected by the lock along with data (deque)
if (done) // atomic bool
{
return;
}
deque.push_back(item);
}
cv.notify_one();
}
// C)
void Enqueue(T item)
{
{
std::lock_guard<std::mutex> lock(mtx); // done is NOT atomic bool and is protected by the lock along with data (deque)
if (done) // simple bool
{
return;
}
deque.push_back(item);
}
cv.notify_one();
}
ウェイターは:
bool Dequeue(T& item)
{
std::unique_lock<std::mutex> lock(mtx);
while (!done && deque.empty())
{
cv.wait(lock);
}
if (!deque.empty())
{
item = deque.front();
deque.pop_front();
}
if (done)
{
return false;
}
return true;
}
質問を絞り込んでください。フォーカスの不足があるようです。 –
どのような焦点を意味しますか?質問から明らかでないことは何ですか?私は質問を指定します... – Dom
すでに曖昧なスレッドライブラリでアトミックを使用することの「正確さ」をタイトルで尋ねています。次に、身体の中で2つの質問をしました。条件変数の前にロックが必要かどうか。多くの実装のどれが「より良い」ものであり、これもあいまいである。どちらかを選択し、可能な限り객관的に答えてください。 –