Код: Выделить всё
#include
#include
#include
int main() {
std::atomic key;
auto t1 = std::thread([&]() {
auto now = std::chrono::steady_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::steady_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++, правда ли, что только один поток может гарантировать линеаризуемость? То есть операция загрузки гарантированно всегда считывает хранилище, которое произошло ближе всего к временной шкале до того, как произошла операция загрузки.
Полный случай заключается в том, что создается задача поиска для каждого ввода пользователя и отбрасывается ответ, если значение изменилось, чтобы смоделировать то, что происходит в javascript.
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
// =================================================================
// 1. TASK DISPATCHER (The "Event Loop")
// This class mimics the JavaScript Task Queue. It allows background
// threads to "post" work back to the main thread for execution.
// =================================================================
class Dispatcher {
std::queue tasks;
std::mutex mtx;
public:
// Pushes a function into the queue. Safe to call from any thread.
void post(std::function task) {
std::lock_guard lock(mtx);
tasks.push(task);
}
// Executes all pending tasks. Should be called by the Main Thread.
void processEvents() {
std::queue toExecute;
{
// Swap content to minimize lock time (prevents blocking posters)
std::lock_guard lock(mtx);
std::swap(toExecute, tasks);
}
while (!toExecute.empty()) {
toExecute.front()(); // Execute the callback
toExecute.pop();
}
}
};
Dispatcher g_dispatcher; // Global dispatcher acting as our event loop
// =================================================================
// 2. MOCK NETWORK FUNCTION
// Simulates an asynchronous network request.
// =================================================================
void fetchNetworkData(int inputValue, std::function callback) {
// Start a background thread to simulate network latency
std::thread([inputValue, callback]() {
// Simulate a 2-second delay
std::this_thread::sleep_for(std::chrono::seconds(2));
std::string result = "Data_for_" + std::to_string(inputValue);
// IMPORTANT: Instead of running the callback here (in the background thread),
// we post it back to the dispatcher so it runs on the Main Thread.
g_dispatcher.post([callback, result]() {
callback(result);
});
}).detach();
}
// =================================================================
// 3. SEARCH COMPONENT
// Handles the core logic: capturing input and validating responses.
// =================================================================
class SearchComponent {
int m_latestValue = -1; // State: holds the most recent input from the user
public:
void onUserInput(int newValue) {
m_latestValue = newValue;
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/79857222/is-it-true-that-only-a-single-thread-can-guarantee-the-linearizability[/url]
Мобильная версия