See the code below, AsyncTask
creates a peer thread(timer) to increment a atomic variable and sleep for a while. The expected output is to print counter_
10 times, with values ranging from 1 to 10, but the actual result is strange:
- It seems like that the actual result is random, sometimes it's printed once, sometimes it's not printed at all.
- Further, I found that when I changed thread sleep time(both peer thread and main thread) to seconds or milliseconds, the program worked as expected.
#include <atomic>
#include <thread>
#include <iostream>
class AtomicTest {
public:
int AsyncTask() {
std::thread timer([this](){
while (not stop_.load(std::memory_order_acquire)) {
counter_.fetch_add(1, std::memory_order_relaxed);
std::cout << "counter = " << counter_ << std::endl;
std::this_thread::sleep_for(std::chrono::microseconds(1)); // both milliseconds and seconds work well
}
});
timer.detach();
std::this_thread::sleep_for(std::chrono::microseconds(10));
stop_.store(true, std::memory_order_release);
return 0;
}
private:
std::atomic<int> counter_{0};
std::atomic<bool> stop_{false};
};
int main(void) {
AtomicTest test;
test.AsyncTask();
return 0;
}
I know that thread switching also takes time, is it because thread sleep time too short?
My programme running environment:
- Apple clang version 14.0.0 (clang-1400.0.29.202)
- Target: arm64-apple-darwin22.2.0)