类 UNIX 操作系统中的系统调用是可重入的(即可以并行执行多个系统调用)。在 C/C++11 发生之前关系的意义上,这些系统调用是否有任何排序约束?
例如,让我们考虑以下具有 3 个线程的程序(在伪代码中):
// thread 1
store x 1
store y 2
// thread 2
store y 1
store x 2
// thread 3
Thread.join(1 and 2)
wait((load x) == 1 && (load y) == 1)
在这里,假设x
和y
是共享位置,并且所有的load
和store
s 都具有宽松的顺序。(注意:对于宽松的原子访问,竞态不被视为错误;它们在 C/C++11 语义的意义上是有意store x 1
的。)该程序可能会终止,因为 (1) 编译器可能重新排序and store y 2
,然后 (2) 执行store y 2
, store y 1
, store x 2
, 然后store x 1
, 所以 (3) 线程 3 可以同时读取x = 1
和y = 1
。
我想知道以下程序是否也可能终止。这里,在线程 1 和 2 中分别插入了一些系统调用syscall1()
& :syscall2()
// thread 1
store x 1
syscall1()
store y 2
// thread 2
store y 1
syscall2()
store x 2
// thread 3
Thread.join(1 and 2)
wait((load x) == 1 && (load y) == 1)
该程序似乎无法终止。但是,在没有调用的系统调用的排序约束的情况下,我认为这个程序可能会终止。这就是原因。假设syscall1()
并syscall2()
没有被序列化并且可以并行运行。然后,编译器在完全了解 and 的语义的情况下syscall1()
,syscall2()
仍然可以重新排序store x 1
& syscall1()
and store y 2
。
所以我想问一下不同线程调用的系统调用是否有任何排序约束。如果可能的话,我想知道这类问题的权威来源。