このスレッドで正しい質問をしていますか??? もしそうなら、彼らは正しく答えられていますか???
または別の言い方をすると:
私はここで物事を完全に誤解していますか??
段落を編集: StatementOnOrder (以下を参照) が false のようです。link1 ( Linux での C++ スレッドなどは多くの場合、pthreads に基づいています) とlink2 (決定要因として現在のスケジューリング ポリシーに言及しています) を参照してください - cppreference ( ref ) の Cubbi に感謝します。リンク、リンク、リンク、リンクも参照してください。ステートメントが false の場合は、以下のコードに示すように、アトミック (!) チケットをプルする方法がおそらく優先されます!!
ここに行きます...
StatementOnOrder : 「ロックされたミューテックスに実行され、特定の順序で「スリープ状態になる」複数のスレッドは、その後ミューテックスの所有権を取得し、同じ順序で続行します。
質問: StatementOnOrderはtrue または falseですか???
void myfunction() {
std::lock_guard<std::mutex> lock(mut);
// do something
// ...
// mutex automatically unlocked when leaving funtion.
}
このページのこれまでのすべてのコード例は、次のいずれかのように見えるため、これを尋ねています。
a) 無駄 ( StatementOnOrderが true の場合)
また
b) 重大な間違い ( StatementOnOrderが false の場合)。
では、 StatementOnOrderが falseの場合、なぜ「深刻に間違っている」可能性があると言うのでしょうか?
その理由は、すべてのコード例は を利用することで非常にスマートであると考えていますがstd::condition_variable
、実際にはその前にロックを使用しているため、( StatementOnOrderが false の場合) 順序が台無しになります!!! 皮肉なことに、
このページで を検索してください。std::unique_lock<std::mutex>
したがって、StatementOnOrderが本当に false の場合、ロックに遭遇することはなく、その後チケットや condition_variables を処理することはできません。代わりに、次のようなことを行う必要があります:ロックに遭遇する前にアトミック チケットを取得します!!! ロックに遭遇する前に
、なぜチケットを引くのですか? ここではStatementOnOrderが false であると想定しているため、順序付けは「悪」ロックの前に行う必要があります。
#include <mutex>
#include <thread>
#include <limits>
#include <atomic>
#include <cassert>
#include <condition_variable>
#include <map>
std::mutex mut;
std::atomic<unsigned> num_atomic{std::numeric_limits<decltype(num_atomic.load())>::max()};
unsigned num_next{0};
std::map<unsigned, std::condition_variable> mapp;
void function() {
unsigned next = ++num_atomic; // pull an atomic ticket
decltype(mapp)::iterator it;
std::unique_lock<std::mutex> lock(mut);
if (next != num_next) {
auto it = mapp.emplace(std::piecewise_construct,
std::forward_as_tuple(next),
std::forward_as_tuple()).first;
it->second.wait(lock);
mapp.erase(it);
}
// THE FUNCTION'S INTENDED WORK IS NOW DONE
// ...
// ...
// THE FUNCTION'S INDENDED WORK IS NOW FINISHED
++num_next;
it = mapp.find(num_next); // this is not necessarily mapp.begin(), since wrap_around occurs on the unsigned
if (it != mapp.end()) {
lock.unlock();
it->second.notify_one();
}
}
上記の関数は、プルされたアトミック チケットに従って注文が実行されることを保証します。(編集:ブーストの侵入型マップを使用して、(ローカル変数として) スタックに condition_variable を保持することは、フリーストアの使用を減らすためにここで使用できる優れた最適化です! )
しかし、主な質問は次のとおりです。StatementOnOrderはtrue ですか、それとも false ですか?
(もしそれが本当なら、上記の私のコード例も無駄であり、mutex を使用するだけで完了できます。) Anthony Williamsのような誰かがこのページをチェックしてくれること
を願っています... ;)