gpt4 book ai didi

linux - Linux 阻塞 I/O 实际上是如何工作的?

转载 作者:IT王子 更新时间:2023-10-29 00:18:36 25 4
gpt4 key购买 nike

在 Linux 中,当您进行诸如读取或接受之类的阻塞 i/o 调用时,实际会发生什么?

我的想法:进程从运行队列中取出,在某个等待队列中进入等待或阻塞状态。然后,当建立 tcp 连接(接受)或硬盘准备就绪或读取文件时,会引发硬件中断,让那些等待唤醒和运行的进程(在文件读取的情况下,如何linux 知道要唤醒哪些进程,因为可能有很多进程在等待不同的文件?)。或者可能不是硬件中断,而是单个进程本身轮询以检查可用性。不确定,帮忙?

最佳答案

每个 Linux 设备的实现似乎略有不同,并且随着添加更安全/更快的内核功能,首选方式似乎每隔几个 Linux 版本就会有所不同,但通常:

  1. 设备驱动程序创建读和为设备编写等待队列。
  2. 任何想要等待的进程线程因为 i/o 被放在适当的等待队列。当中断发生时处理程序唤醒一个或多个等待线程。 (显然线程不会立即运行,因为我们处于中断状态上下文,但被添加到内核的调度队列)。
  3. 当内核调度线程检查是否有条件继续进行是正确的 - 如果不是它返回等待队列。

一个典型的例子(稍微简化):

初始化时在驱动程序中:

    init_waitqueue_head(&readers_wait_q);

在驱动程序的读取函数中:

    if (filp->f_flags & O_NONBLOCK)
{
return -EAGAIN;
}
if (wait_event_interruptible(&readers_wait_q, read_avail != 0))
{
/* signal interrupted the wait, return */
return -ERESTARTSYS;
}
to_copy = min(user_max_read, read_avail);
copy_to_user(user_buf, read_ptr, to_copy);

然后中断处理程序只发出:

    wake_up_interruptible(&readers_wait_q);

请注意,wait_event_interruptible() 是一个宏,它隐藏了一个检查条件的循环 - read_avail != 0 在这种情况下 - 如果在条件为不是真的。

如前所述,有许多变体 - 主要的一个是如果中断处理程序可能有很多工作要做,那么它自己会做最少的工作并将其余的推迟到工作队列或 tasklet(通常被称为“下半部分”),它会唤醒等待的线程。

有关更多详细信息,请参阅 Linux 设备驱动程序书籍 - 此处提供 pdf: http://lwn.net/Kernel/LDD3

关于linux - Linux 阻塞 I/O 实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2777192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com