- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
关于这个问题Is there cases where a 32-bit variable could not been properly-aligned以及提供的答案,我可以假设我可以在 Windows 平台下工作时交换地址而没有任何副作用吗?
例如:
struct Foo
{
// whatever Foo can hold
};
struct Bar
{
void buildFoo()
{
auto tmp = new Foo;
// do some stuff on tmp, or not
foo = tmp;
}
Foo* foo;
};
现在,让一些线程通过 Bar
的实例使用 foo
,而其他线程调用 Bar::buildFoo()
?
最佳答案
C++ 标准
否,不能保证同时修改/访问原始2 指针是c++ 中的原子操作。
C++ 标准规定,如果一个线程修改内存位置而另一个线程修改/访问相同的内存位置,则存在数据竞争,如果存在这样的数据竞争,则程序会出现未定义的行为.
[intro.multithread]
4)
Two expressions evaluations conflict if one of them modifies a memory location (1.7) and the other one accesses or modifies the same memory location.
...
21)
The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such dat race results in undefined behavior.
1. raw 未被包裹在 std::atomic<Foo*>
中,或等效物。
实现特定行为(windows 32/64 位)
在 Windows 下,保证读/写正确对齐 32-bit
正如 the article 所述,变量总是原子的由 question/answer 链接你之前提到过。
访问正确对齐的 64-bit
变量在 64-bit
上也是原子的 window 。
Interlocked Variable Access - http://msdn.microsoft.com/en-us/library/ms684122%28VS.85%29.aspx
Simple reads and writes to properly-aligned 32-bit variables are atomic operations. In other words, you will not end up with only one portion of the variable updated; all bits are updated in an atomic fashion.
However, access is not guaranteed to be synchronized. If two threads are reading and writing from the same variable, you cannot determine if one thread will perform its read operation before the other performs its write operation.
这是什么意思?
标准说的是一回事,而 Microsoft 的文档说的是另一回事。我们应该信任和合作哪些?这当然取决于我们在做什么。
如果我们只为 windows 平台开发,我们可以阅读所用编译器在代码生成方面的保证,然后从那里开始,但是如果我们想编写可以在不同平台下编译和运行的代码,唯一的方法就是正确信任的东西是标准。
所以在 Windows 下工作时我可以安全地交换 32 位变量?
如果您所说的“交换” 是指如下代码片段中所写的操作,则答案是否,但如果您的意思是“分配" 答案是是。
void swap (int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
int main () {
int x = 1;
int y = 2;
swap (x, y);
}
上面的代码片段(或前面提到的文档)中没有任何内容表明这将是一个原子操作,并且在查看我们的 swap
的实现时我们很容易看到操作没有正确同步。
读/写单个 32 位变量在 Windows 下是安全的,但在上面没有任何东西可以保证 x
和 y
没有值 2
当我们在 swap
的中间时.
但是,保证x
never 将包含前一个 x
中 50% 的字节和 y
中 50% 的字节,或类似的.. 个人写入是原子的。
关于c++ - 指针地址交换总是 C++ 中的原子操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22038298/
有没有办法用连词创建原子 if ?也就是说,我可以以某种方式在 C 中自动测试 if(A && B) 吗?如果它在第一个连接处短路,那么没问题,但如果没有短路,则在检查 B 时,A 可能已更改。有什么
我有很多 fork 的过程。子进程做很多事情和另一个系统调用。 当任何子进程从系统调用中获取错误时,它会将错误描述打印到 stderr 并将 SIGUSR1 发送到组长(主要父进程)。 SIGUSR1
阅读 boost::atomic 上的文档和 std::atomic 让我感到困惑的是 atomic 是否接口(interface)应该支持非平凡类型? 也就是说,给定一个只能通过将读/写包含在一个完
我有一个命令,可以将叠加图像放在视频上。 之后,我调整输出大小以适合某些尺寸。 通常一切正常,但有时且仅在某台台式计算机上,当第二次精化开始时,命令返回错误:moov atom not found 让
我最近发现当 LANG 设置为 C.utf8 时,X11 原子 WM_NAME 未在 Swing JFrame 中设置。但为 LANG 的其他值设置。这发生在带有 OpenJDK 11.0.9 的 L
我目前正在使用blackmagic的prorecorder录制视频。我使用 ffmpeg 将视频即时转码为 mp4 视频容器。持续时间未知,因为我正在对 prorecorder 输出到命名管道的 .t
这里真的有人使用 atom 来处理 git 提交消息吗?我想但我遇到了这个问题并且一直坚持使用 git commit -m '....' 。当我尝试使用 atom 时,它会打开 atom,我几乎立即从
考虑: void foo() { std::vector> foo(10); ... } foo 的内容现在有效吗?或者我是否需要显式循环并初始化它们?我检查过 Godbolt,看起来不错,但
在official FAQ我阅读的 Memcached: “发送到 memcached 的所有单独命令都是绝对原子的。” 然而,当涉及到 get_multi 和 set_multi 时,我仍然不清楚。
在测试程序的可扩展性时,我遇到了必须将 memcpy 操作设置为原子操作的情况。我必须将 64 字节的数据从一个位置复制到另一个位置。 我遇到了一种解决方案,即使用旋转变量: struct recor
我对 C++ 原子变量感到困惑。如果我有一个原子 x,我想在一个线程中递增并在另一个线程中读取,我可以执行++x 还是必须执行 x.atomic_fetch_add(1)。在读者线程中,我可以做类似
跟进自 Multiple assignment in one line ,我很想知道这对原子数据类型是如何工作的,特别是 bool 类型的例子。 给定: class foo { std::at
我想创建一个版本控制系统,并且对版本号为 1 的新条目的查询如下所示: ID 和修订号组合起来就是主键。 insert into contentfile (id, name, revision, ac
我在 iOS 项目中有下一个独立的测试片段: /// ... std::atomic_bool ab; ab.store(true); bool expected = false; while (!a
我了解如何使用条件变量(此构造的名称很糟糕,IMO,因为 cv 对象既不是变量也不表示条件)。所以我有一对线程,canonically使用 Boost.Thread 设置为: bool awake =
因此,对于最终项目,我尝试制作一款包含三种不同 meteor 的游戏;铜牌、银牌和金牌。虽然青铜阵列在Setup()中工作正常,但银色和金色 meteor 由于某种未知原因而高速移动。 functio
第一个问题,为什么不在 atomic_compare_exchange_weak 操作的参数中应用后缀求值 (++)?运算前后a的值相同。然而,当在 printf() 中使用时,正如预期的那样,该值会
我正在尝试使用 OpenMP 对已经矢量化的代码进行内部函数并行化,但问题是我使用一个 XMM 寄存器作为外部“变量”,我会在每个循环中递增。现在我正在使用 shared 子句 __m128d xmm
clojure“atom”的文档指出 - "Changes to atoms are always free of race conditions." 但是,竞争条件不仅根据更改定义,而且在不同线程中
我一直在研究原子引用计数的实现。 库之间的大多数操作都非常一致,但我在“减少引用计数”操作中发现了惊人的多样性。 (请注意,通常情况下,shared 和 weak decref 之间的唯一区别是调用了
我是一名优秀的程序员,十分优秀!