我的问题是关于 C#(大概还有 .Net)中的执行顺序保证。我给出了我所了解的 Java 示例来进行比较。
对于Java(来自《Java并发实践》)
只要在该线程内无法检测到重新排序,就无法保证一个线程中的操作将按照程序给定的顺序执行,即使重新排序对于其他线程来说是显而易见的。
所以代码
y = 10;
x = 5;
a = b + 10;
实际上可以在赋值 y = 10 之前赋值 a=b+10
在 Java 中(来自同一本书)
当线程 A 启动由同一锁保护的同步块时,线程 A 在同步块中或同步块之前所做的所有操作对于线程 B 都是可见的。
所以在Java中
y = 10;
synchronized(lockObject) {
x = 5;
}
a = b + 10;
y = 10 和 x = 5 保证都在 a = b + 10 之前运行(我不知道 y = 10 是否保证在 x = 5 之前运行)。
C# 代码如何保证 C# 语句的执行顺序
y = 10;
lock(lockObject) {
x = 5;
}
a = b + 10;
我对一个可以提供明确参考或其他真正有意义的理由的答案特别感兴趣,因为这样的保证很难测试,因为它们是关于允许编译器做什么,而不是每次做什么,因为当它们失败时当线程以错误的顺序命中事物时,您将很难重现间歇性错误。
ISO 23270:2006 —信息技术—编程语言—C# http://standards.iso.org/ittf/PubliclyAvailableStandards/c042926_ISO_IEC_23270_2006%28E%29.zip,§10.10 说(我引用):
10.10 执行顺序执行应继续进行,以便每个执行线程的副作用
在关键执行点保留。 A副作用被定义为
作为对易失性字段的读取或写入、对非易失性变量的写入,
写入外部资源并引发异常。
这些副作用发生顺序的关键执行点
应保留对易失性字段的引用(第 17.4.3 节),
lock
语句(§15.12),以及线程的创建和终止。
实现可以自由改变 C# 程序的执行顺序,
受以下限制:
数据依赖性保留在执行线程内。
那是,每个变量的值的计算就像所有语句一样
线程中的内容按原始程序顺序执行。(强调我的)。
保留初始化排序规则(§17.4.4、§17.4.5)。
相对于易失性读取,保留副作用的顺序
并写道(§17.4.3)。此外,实现不需要评估部分
表达式,如果它可以推断出该表达式的值未被使用并且没有
产生所需的副作用(包括由调用方法或
访问易失性字段)。当程序执行被异步中断时
事件(例如另一个线程抛出的异常),不保证
可观察到的副作用在原始程序顺序中是可见的。
其他 CLI 标准同样可用gratis来自 ISO
- ISO 23271:2006 — *信息技术 — 通用语言基础设施 (CLI) 分区 I 至 VI http://standards.iso.org/ittf/PubliclyAvailableStandards/c042927_ISO_IEC_23271_2006%28E%29.zip
- ISO 23272:2006 —信息技术—通用语言基础设施(CLI)—关于从分区 IV XML 文件导出的信息的技术报告 http://standards.iso.org/ittf/PubliclyAvailableStandards/c042928_ISO_IEC_TR_23272_2006%28E%29.zip
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)