|
|
1
44
起初,人们可能认为本机大小的读写是原子的,但是有许多问题需要处理,包括处理器/核心之间的缓存一致性。在Windows和Linux上使用类似于interlocked*的原子操作。C++0x将有一个“原子”模板将它们封装在一个漂亮的跨平台接口中。目前,如果您使用的是平台抽象层,那么它可能提供这些功能。 ACE 是的,请参见类模板 ACE_Atomic_Op . |
|
|
2
64
孩子,真是个问题。答案是:
这都归结到系统的体系结构。在IA32上,正确对齐的地址将是原子操作。未对齐的写入可能是原子的,这取决于正在使用的缓存系统。如果内存位于单个一级缓存线内,那么它是原子的,否则它不是。CPU和RAM之间总线的宽度会影响原子性质:8086上正确对齐的16位写入是原子的,而8088上相同的写入并不是因为8088只有8位总线,而8086只有16位总线。 此外,如果使用C/C++,不要忘记将共享值标记为易失性,否则优化器会认为变量永远不会在一个线程中更新。 |
|
|
3
11
如果您正在读/写4字节的值,并且它在内存中是双字对齐的,并且您正在I32体系结构上运行,那么读和写是原子的。 |
|
|
4
8
是的,您需要同步访问。在C++0x中,它将是一个数据竞争和未定义行为。对于POSIX线程,它已经是未定义的行为。 在实践中,如果数据类型大于本机字大小,可能会得到错误的值。另外,由于优化移动读和/或写,另一个线程可能永远看不到写入的值。 |
|
|
5
3
您必须进行同步,但在某些体系结构中,有有效的方法可以实现同步。 最好的方法是使用子例程(可能隐藏在宏后面),这样就可以有条件地用特定于平台的实现替换实现。 Linux内核已经有了一些这样的代码。 |
|
|
6
3
在Windows上,互锁的***交换***添加保证是原子的。 |
|
|
7
1
为了呼应楼上所有人所说的,语言pre-c++0x不能保证从多个线程访问共享内存。任何保证都取决于编译器。 |
|
|
8
1
绝对不!
来自我们最高C++权威的答案,M. Boost:
|
|
|
9
0
不,他们不是(或者至少你不能假设他们是)。尽管如此,原子性地实现这一点还是有一些诀窍的,但它们通常不可移植(参见 Compare-and-swap ) |
|
|
10
0
我同意很多,尤其是 Jason . 在Windows上,可能会使用InterlockedAdd及其朋友。 |
|
|
11
0
从上面提到的缓存问题中分配… 如果将代码移植到寄存器较小的处理器上,那么它就不再是原子的了。 在我看来,线程问题太棘手,无法冒险。 |
|
|
12
0
举个例子
第一条语句被假定为原子语句,因为它转换为占用单个CPU周期的单个inc汇编指令。但是,第二个分配需要几个操作,因此显然不是原子操作。 另一个,
同样,您必须分解代码来看看这里到底发生了什么。 |
|
|
13
0
锝 我认为一旦你使用一个常量(比如6),指令就不会在一个机器周期内完成。 与x相比,尝试查看x+=6的指令集++ |
|
|
14
0
有些人认为,++C是原子的,但是他们关注生成的程序集。例如,使用“gcc-s”时:
为了增加一个int,编译器首先将其加载到一个寄存器中,然后将其存储回内存中。这不是原子的。 |
|
|
15
-1
唯一可移植的方法是为编译器使用在signal.h头文件中定义的sig_atomic_t类型。在大多数C和C++实现中,这是int。然后将变量声明为“易失性SiguAuthIcIt”。 |
|
|
vitaminC · 执行程序时无法理解tryLock方法 2 年前 |
|
|
Ronald · 用Java同步此vs字段 2 年前 |
|
|
Uuuuuumm · 当一个方法被并发方法调用时,我如何同步运行它 2 年前 |
|
|
wpunkts · 如何使用外部信号控制视频播放的速度和方向 2 年前 |