- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在玩 C++ Concurrency in Action 中的一个示例,它使用 std::memory_order_relaxed
从 5 个不同的线程读取和写入 3 个原子变量。示例程序如下:
#include <thread>
#include <atomic>
#include <iostream>
std::atomic<int> x(0);
std::atomic<int> y(0);
std::atomic<int> z(0);
std::atomic<bool> go(false);
const unsigned int loop_count = 10;
struct read_values
{
int x;
int y;
int z;
};
read_values values1[loop_count];
read_values values2[loop_count];
read_values values3[loop_count];
read_values values4[loop_count];
read_values values5[loop_count];
void increment( std::atomic<int>* v, read_values* values )
{
while (!go)
std::this_thread::yield();
for (unsigned i=0;i<loop_count;++i)
{
values[i].x=x.load( std::memory_order_relaxed );
values[i].y=y.load( std::memory_order_relaxed );
values[i].z=z.load( std::memory_order_relaxed );
v->store( i+1, std::memory_order_relaxed );
std::this_thread::yield();
}
}
void read_vals( read_values* values )
{
while (!go)
std::this_thread::yield();
for (unsigned i=0;i<loop_count;++i)
{
values[i].x=x.load( std::memory_order_relaxed );
values[i].y=y.load( std::memory_order_relaxed );
values[i].z=z.load( std::memory_order_relaxed );
std::this_thread::yield();
}
}
void print( read_values* values )
{
for (unsigned i=0;i<loop_count;++i)
{
if (i)
std::cout << ",";
std::cout << "(" << values[i].x <<","
<< values[i].y <<","
<< values[i].z <<")";
}
std::cout << std::endl;
}
int main()
{
std::thread t1( increment, &x, values1);
std::thread t2( increment, &y, values2);
std::thread t3( increment, &z, values3);
std::thread t4( read_vals, values4);
std::thread t5( read_vals, values5);
go = true;
t5.join();
t4.join();
t3.join();
t2.join();
t1.join();
print( values1 );
print( values2 );
print( values3 );
print( values4 );
print( values5 );
return 0;
}
每次运行该程序时,我都会得到完全相同的输出:
(0,10,10),(1,10,10),(2,10,10),(3,10,10),(4,10,10),(5,10,10),(6,10,10),(7,10,10),(8,10,10),(9,10,10)
(0,0,1),(0,1,2),(0,2,3),(0,3,4),(0,4,5),(0,5,6),(0,6,7),(0,7,8),(0,8,9),(0,9,10)
(0,0,0),(0,1,1),(0,2,2),(0,3,3),(0,4,4),(0,5,5),(0,6,6),(0,7,7),(0,8,8),(0,9,9)
(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0)
(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0)
如果我从 std::memory_order_relaxed
更改为 std::memory_order_seq_cst
,程序会给出完全相同的输出!
我本以为程序的 2 个版本会有不同的输出。为什么 std::memory_order_relaxed
和 std::memory_order_seq_cst
的输出没有区别?
为什么 std::memory_order_relaxed
每次运行程序总是产生完全相同的结果?
我正在使用: - 作为虚拟机安装的 32 位 Ubuntu(在 VMWare 下) - 英特尔四核处理器 - 海湾合作委员会 4.6.1-9
代码编译为: g++ --std=c++0x -g mem-order-relaxed.cpp -o relaxed -pthread
注意-pthread是必须的,否则报如下错误: 在抛出“std::system_error”的实例后调用终止 what(): 不允许操作
我看到的行为是由于缺乏 GCC 支持还是在 VMWare 下运行的结果?
最佳答案
您为 VM 分配了多少个处理器内核?为 VM 分配多个核心以使其利用并发性。
关于c++ - 为什么 memory_order_relaxed 和 memory_order_seq_cst 没有区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9886246/
给定: std::atomic x; uint64_t f() { x.store(20, std::memory_order::memory_order_relaxed); x.st
在 ThreadMethodOne 中加载时放宽变量 valA 和 valB 同步的最正确方法是什么(假设不存在 valA 和 valB 的虚假高速缓存行共享)?似乎我不应该将 ThreadMetho
假设线程 1 正在对变量 v 进行原子存储使用 memory_order_release (或任何其他顺序)并且线程 2 正在对 v 执行原子读取使用 memory_order_relaxed . 在
Stackoverflow 上已经有一些问题本质上是关于 memory_order_relaxed 的用例,例如: Understanding memory_order_relaxed What ar
C++ 内存模型放宽了原子性,不对内存操作提供任何顺序保证。除了我在这里找到的 C 中的邮箱示例: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1
Cppreference 给出 following example关于memory_order_relaxed: Atomic operations tagged memory_order_relax
读取 atomic_uint 的值有什么区别?使用 memory_order_relaxed,并读取 volatile unsigned int 的值(假设 volatile 操作是原子的)? 具体来
我试图了解 memory_order_relaxed 的细节。我指的是这个链接:CPP Reference . #include #include std::atomic ptr {nullptr
考虑以下摘自 Herb Sutter 关于原子的演讲的代码片段: smart_ptr 类包含一个名为 control_block_ptr 的 pimpl 对象,其中包含引用计数 refs。 // Th
我在看 this article来自 GCC Wiki 关于 C++ 内存屏障(及其很棒的)。 在我到达这一点之前,它非常简单: 相反的方法是 std::memory_order_relaxed。该模
据我所知,memory_order_relaxed 是为了避免昂贵的内存栅栏,这可能需要在特定架构上进行更多约束排序。在那种情况下,如何在流行的处理器上实现原子变量的总修改顺序? 编辑: atomic
下面是否保证打印 1 后跟 2? auto&& atomic = std::atomic{0}; std::atomic* pointer = nullptr; // thread 1 auto&&
我有一个写入原子变量的线程。 (使用 memory_order_release)。 线程 A 还有许多其他线程读取该变量。 (使用 memory_order_acquire)。 线程 B。 在线程 A
关于内存顺序的 cppreference 文档说 Typical use for relaxed memory ordering is incrementing counters, such as t
我正在研究这个网站:https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync ,这对理解关于原子类的话题非常有帮助。 但是这个放松模式的例子很难理解:
假设我有一个线程 A 写入 atomic_int x = 0;,使用 x.store(1, std::memory_order_relaxed);。如果没有任何其他同步方法,使用 x.load(std
在以下代码中使用 std::memory_order_relaxed 是否正确? #include #include #include #include using namespace std
我正在研究 C++ 内存序列,但它很困惑。 例如: void sumUp(std::atomic& sum, std::vector& val) { int tmpSum = 0; for
C++ 标准规定,原子上的 RMW(读-修改-写)操作将对原子变量的最新值进行操作。因此,当从多个线程并发执行时,对这些操作使用 memory_order_relaxed 不会影响 RMW 操作。 我
std::atomic cnt = {2}; thread 1: doFoo(); if (cnt.fetch_sub(1, std::memory_order_relaxed) ==
我是一名优秀的程序员,十分优秀!