Code: Select all
#include
#include
#include
int main() {
std::atomic key;
auto t1 = std::thread([&]() {
auto now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto seconds =
std::chrono::duration_cast(duration).count();
key.store(seconds); // #1 occurred at timepoint `T1`
});
auto t2 = std::thread([&]() {
auto now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto seconds =
std::chrono::duration_cast(duration).count();
key.store(seconds); // #2 occurred at timepoint `T2`
});
auto t3 = std::thread([&]() {
std::this_thread::sleep_for(std::chrono::milliseconds(300)); // debounce
auto search_key = key.load(); // #3 occurred at timepoint `T3`
// request(search_key);
});
t1.join();
t2.join();
t3.join();
}
In diesem Beispiel werden die beiden Eingabeereignisse des Benutzers modelliert, nämlich t1 und t2. Angenommen, jedes Ereignis trat zu dem im Kommentar angegebenen Zeitpunkt auf und T1 < T2 < T3. Auch wenn jede atomare Operation seq_cst verwendet und eine einzige Gesamtreihenfolge bildet und die Zeitpunkte T1 und T2 beide vor T3 liegen, kann #3 immer noch #1 laden und vor #2 kohärenzgeordnet sein.
Dies ist keine Linearisierbarkeit, da T1 < T2 < T3 und die Ladung bei T3 den Speicher nicht gelesen haben das geschah bei T2. (Ich bin mir nicht sicher, ob die Konsistenz in der Zeitleiste als Linearisierbarkeit bezeichnet werden kann).
Ist es also aus Sicht des C++-Standards wahr, dass nur ein einzelner Thread Linearisierbarkeit garantieren kann? Das heißt, der Ladevorgang liest garantiert immer den Speicher, der vor dem Ladevorgang am nächsten an der Zeitachse stattfand.
Mobile version