订购UNIX系统调用的规范

时间:2016-03-26 13:08:49

标签: c++ linux multithreading unix happens-before

类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)

此处,假设xy是共享位置,并且所有loadstore都具有宽松排序。 (注意:对于放松的原子访问,比赛不被视为错误;它们在C / C ++ 11语义的意义上是故意的。)此程序可能会终止,因为(1)编译器可能会重新排序{ {1}}和store x 1,然后(2)执行store y 2store y 2store y 1,然后执行store x 2,以便(3)线程3可以同时阅读store x 1x = 1

我想知道以下程序是否也可以终止。在这里,一些系统调用y = 1& {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()的语义的情况下,仍然可以重新排序syscall1()& syscall2()store x 1

所以我想询问是否存在由不同线程调用的系统调用的任何排序约束。如果可能的话,我想知道这类问题的权威来源。

1 个答案:

答案 0 :(得分:1)

从用户土地上的应用程序的角度来看,system callsyscalls(2) ...中列出的那些)是基本操作。

每个系统调用(按照定义)通过一些单个 machine code指令(SYSENTERSYSCALLINT调用内核。 ..);细节取决于处理器(其instruction set)和ABI。 kernel开展业务(处理系统调用 - 可能成功或失败),但您的用户程序只能看到一个基本步骤。有时这一步骤(在内核控制期间)可以持续长时间(例如几分钟或几小时)。

因此user land中的程序在低级虚拟机中运行,由处理器的user mode计算机指令提供,并由单个虚拟"系统调用指令(能够执行内核实现的任何系统调用)。

这并不是因为竞争条件而禁止你的程序出错。