Код: Выделить всё
#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();
}
В этом примере он моделирует два таких события ввода пользователя, а именно t1 и t2. Предполагается, что каждое событие произошло в момент времени, указанный в комментарии, и T1 < T2 < T3. Несмотря на то, что каждая атомарная операция использует seq_cst и формирует единый общий порядок, а моменты времени T1 и T2 предшествуют T3, #3 все равно может загрузить #1 и упорядочить по связности до #2.
Это не линеаризуемость, поскольку T1 < T2 < T3 и загрузка в T3 не прочитали хранилище, которое произошло в T2. (Я не уверен, можно ли назвать согласованность на временной шкале линеаризуемостью).
Итак, с точки зрения стандарта C++, правда ли, что только один поток может гарантировать линеаризуемость? То есть операция загрузки гарантированно всегда считывает хранилище, которое произошло ближе всего к временной шкале до того, как произошла операция загрузки.
Подробнее здесь: https://stackoverflow.com/questions/798 ... rizability
Мобильная версия