memory_order_relaxed的一些用例是什么
What are some use cases for memory_order_relaxed
C++内存模型具有宽松的原子,它不对内存操作提供任何排序保证。除了我在这里找到的C中的邮箱示例:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1525.htm
基于本文中的激励示例:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2153.pdf
我很好奇这种类型的同步机制的其他用例。
我在工作中经常看到的一个简单例子是统计计数器。如果你想要统计事件发生的次数,但不需要任何类型的除了确保增量安全之外,还可以跨线程同步,使用memory_order_relaxed
是有道理的。
static std::atomic<size_t> g_event_count_;
void HandleEvent() {
// Increment the global count. This operation is safe and correct even
// if there are other threads concurrently running HandleEvent or
// PrintStats.
g_event_count_.fetch_add(1, std::memory_order_relaxed);
[...]
}
void PrintStats() {
// Snapshot the "current" value of the counter. "Current" is in scare
// quotes because the value may change while this function is running.
// But unlike a plain old size_t, reading from std::atomic<size_t> is
// safe.
const size_t event_count =
g_event_count_.load(std::memory_order_relaxed);
// Use event_count in a report.
[...]
}
在这两种情况下,都不需要使用更强的内存顺序。关于一些平台,这样做可能会对性能产生负面影响。
在这种情况下,事件读取器可以连接到X11套接字,其中事件的频率取决于用户操作(调整窗口大小、键入等(。如果GUI线程的事件调度器定期检查事件(例如,由于用户应用程序中的一些计时器事件(,我们不想通过获取共享事件队列的锁来不必要地阻止事件读取器线程,因为我们知道共享事件队列是空的。我们可以简单地通过使用"dataReady"原子来检查是否有任何东西已经排队。这也被称为"双重检查锁定"模式。
namespace {
std::mutex mutex;
std::atomic_bool dataReady(false);
std::atomic_bool done(false);
std::deque<int> events; // shared event queue, protected by mutex
}
void eventReaderThread()
{
static int eventId = 0;
std::chrono::milliseconds ms(100);
while (true) {
std::this_thread::sleep_for(ms);
mutex.lock();
eventId++; // populate event queue, e.g from pending messgaes on a socket
events.push_back(eventId);
dataReady.store(true, std::memory_order_release);
mutex.unlock();
if (eventId == 10) {
done.store(true, std::memory_order_release);
break;
}
}
}
void guiThread()
{
while (!done.load(std::memory_order_acquire)) {
if (dataReady.load(std::memory_order_acquire)) { // Double-checked locking pattern
mutex.lock();
std::cout << events.front() << std::endl;
events.pop_front();
// If consumer() is called again, and producer() has not added new events yet,
// we will see the value set via this memory_order_relaxed.
// If producer() has added new events, we will see that as well due to normal
// acquire->release.
// relaxed docs say: "guarantee atomicity and modification order consistency"
dataReady.store(false, std::memory_order_relaxed);
mutex.unlock();
}
}
}
int main()
{
std::thread producerThread(eventReaderThread);
std::thread consumerThread(guiThread);
producerThread.join();
consumerThread.join();
}
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- "The order of evaluation of expressions is left to right."是什么意思
- std::shared_ptr::owner_before 和 std::owner_less:"owner-based order"到底是什么意思?