C 系统调用中间的上下文切换

C 系统调用中间的上下文切换,c,linux-kernel,operating-system,C,Linux Kernel,Operating System,假设进程中有两个线程。 现在,我们运行以下代码: read(fd, buf, 10); 其中fd是线程之间共享的某个文件描述符(比如静态),buf是线程之间不共享的数组(局部变量) 现在,假设文件是1KB,文件中的前10个字符是“aaaaaaaa”,其余的都是“B”。(“BBBBBB…”) 现在,如果我们只有一个处理器,那么如果我在每个线程中打印它们,BUF的输出是什么 我知道答案是,其中一个数组总是只有A的,而另一个只有B的,但是我不完全理解为什么,因为我认为在这个系统调用(Read)的中间

假设进程中有两个线程。 现在,我们运行以下代码:

read(fd, buf, 10);
其中fd是线程之间共享的某个文件描述符(比如静态),buf是线程之间不共享的数组(局部变量)

现在,假设文件是1KB,文件中的前10个字符是“aaaaaaaa”,其余的都是“B”。(“BBBBBB…”)

现在,如果我们只有一个处理器,那么如果我在每个线程中打印它们,BUF的输出是什么

我知道答案是,其中一个数组总是只有A的,而另一个只有B的,但是我不完全理解为什么,因为我认为在这个系统调用(Read)的中间可能会有一个上下文切换,然后BUF的两个都将有一个As。

是否有可能在系统调用中间发生上下文切换?如果是这样,您认为buf在执行结束时会有什么结果?

现代磁盘不能以10字节的粒度执行读写,而是以扇区为单位执行读写,传统上硬盘驱动器(HDD)是512字节。
在上下文切换之前,将10个字符复制到线程缓冲区的速度非常快,尽管不能保证

一个简单的程序可以让两个线程打印到同一个控制台,一个打印
+
,另一个打印
-
。检查第一次
-
之前的
+
数量。
无论如何,对于原始问题,将数组的大小更改为1024,并从1024个
A
开始,您很可能会看到差异。

通过内核、I/O请求块、驱动程序、硬件接口、驱动控制器和缓存的路径漫长而曲折。此外,还应用了足够的锁定来管理此类“重叠”请求。在我工作过的每个系统上,用户线程都会觉得调用是序列化的,无论何时发生任何可能会改变运行线程集的中断。请记住,大多数磁盘读取的字节粒度都要大得多。即使您读取了10个字节,也很可能读取了512个字节或更多。@MartinJames能否请您发布一个完整的解释,说明尽管中断,为什么会序列化此调用?我不知道
read
函数,但在2006年的linux中似乎是这样的。我不知道现在的情况,这能回答你的问题吗?