Kar*_*gha 9 .net multithreading cil atomic
我正在玩MSIL反编译器 - ILDASM,我试图反编译一个简单的.NET方法.
操作码看起来像这样:
.method private hidebysig static int32 Add(int32 a,
int32 b) cil managed
{
// Code size 18 (0x12)
.maxstack 2
.locals init ([0] int32 c,
[1] int32 d,
[2] int32 CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.5
IL_0003: add
IL_0004: stloc.0
IL_0005: ldarg.1
IL_0006: ldc.i4.s 10
IL_0008: add
IL_0009: stloc.1
IL_000a: ldloc.0
IL_000b: ldloc.1
IL_000c: add
IL_000d: stloc.2
IL_000e: br.s IL_0010
IL_0010: ldloc.2
IL_0011: ret
}
Run Code Online (Sandbox Code Playgroud)
我想知道的是 - 这些操作码是原子的吗?即在抢占式调度内核中,单个操作码在完成执行之前是否有可能被抢占?这里的操作码可以很容易地以1:1的方式映射到asm指令,因为它们具有用于加载,存储,添加等的单独操作码.
但是在更复杂的操作码的情况下呢?比如"call",当操作数是一个方法引用标记时,应首先遵循该方法来解析该方法然后调用?是原子吗?
Jon*_*eet 14
不,并非所有操作码都是原子的.例如,如果您使用stloc或ldloc大于本机指针大小的值类型,则不保证是原子的.
ECMA 335的第12.6.6节保证了这么多:
符合要求的CLI应保证当对位置的所有写访问都相同时,对正确对齐的内存位置的读写访问权限不大于本机字大小(native int类型的大小)是原子的(参见§12.6.2)尺寸.原子写入除了写入之外不得改变任何位.
......但是有一个说明:
[注意:当native int的大小为32位时,没有保证对8字节数据的原子访问,即使某些实现在数据在8字节边界上对齐时可能执行原子操作.结束说明]
这意味着任何存储或读取的操作代码Int64都不能保证在x86上是原子的,例如......
| 归档时间: |
|
| 查看次数: |
506 次 |
| 最近记录: |