当执行异步I / O,如何内核确定是否完成了I / O操作? [英] When doing asynchronous I/O, how does the kernel determine if an I/O operation is completed?

查看:170
本文介绍了当执行异步I / O,如何内核确定是否完成了I / O操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我问这一些背景。我问这个问题在几个小时前

Some background on why I'm asking this. I asked this question a few hours ago

<一个href=\"http://stackoverflow.com/questions/36489498/when-a-goroutine-blocks-on-i-o-how-does-the-scheduler-identify-that-it-has-stopp\">When在我一个够程块/ O如何调度标识,它已经停止封锁?

其中有答案

所有的I / O必须通过系统调用来完成,而系统调用的方式在去实施,他们总是通过由运行控制code调用。这意味着,当你调用一个系统调用,而不是只调用它直接(从而放弃线程内核的控制权),运行时会通知你想的系统调用,它也它代表够程的。这使得它可以,例如,做一个非阻塞系统调用,而不是一个阻断一个(实质上是告诉内核,请做这件事情,但不是阻塞直到把它完成,立即返回,并让后来一次的结果我知道,准备好了)。这允许它继续做其他的工作,在此期间。

All I/O must be done through syscalls, and the way syscalls are implemented in Go, they are always called through code that is controlled by the runtime. This means that when you call a syscall, instead of just calling it directly (thus giving up control of the thread to the kernel), the runtime is notified of the syscall you want to make, and it does it on the goroutine's behalf. This allows it to, for example, do a non-blocking syscall instead of a blocking one (essentially telling the kernel, "please do this thing, but instead of blocking until it's done, return immediately, and let me know later once the result is ready"). This allows it to continue doing other work in the meantime.

因此​​,从我的理解,是什么golang调度程序是,它可以确保不要让挂了花时间在等待I / O操作的线程。相反,它在某种程度上推迟的责任内核。


So from my understanding, what the golang scheduler does is that it makes sure not to get hung up spending time on threads waiting for I/O operations. Instead, it somehow defers that responsibility to the kernel.

不过,我想这个过程有更深的了解,因为有很多东西都是我不清楚。

However, I want to get a deeper understanding of the process because there a lot of things that are unclear to me.

现在这是我的理解,这可能潜在地是完全错误的。

Right now this is my understanding, which may potentially be completely wrong.


  1. 请I / O请求,如内部的goroutine GET请求到远程服务器

  2. Golang使系统调用来读取一个TCP流,这是一个阻塞操作,但不是等待,它要求内核时,它得到的信息进行通知。调度删除从其队列阻塞够程

  3. 当内核获取所有它转发到旅途中的过程中的信息,并允许调度知道添加够程返回到其队列中。

我正在努力理解是I / O操作的方式,而不创建另一个线程中完成的,以及如何在内核实际上是知道的I / O操作完成。它是通过轮询或有某种中断系统的到位?

What I'm struggling to understand is how the I/O operation is done without creating another thread, and how the kernel actually "knows" the I/O operation is done. Is it through polling or is there some kind of interrupt system in place?

我希望这是意义一些外表。我很新的一个是这个低水平的概念。

I hope this makes some semblance of sense. I'm very new to concepts that are this low level.

推荐答案

下面内核是指核方。它包括操作系统内核code +加载的驱动程序。

The KERNEL below means "kernel side". It includes OS kernel code + loaded drivers.

鉴于你有一个TCP连接到远程服务器。下面是一个例子内核是如何处理异步读/写TCP流。

Given you have a TCP connection to a remote server. Here is an example how Kernel handles asynchronous write/read TCP stream.

当你发送一个字节数组TCP流,内核就会把缓冲流中的RAM和控制DMA系统缓冲区拷贝到网卡。当DMA完成其工作,有调用CPU内部中断。由内核注册的中断处理程序将从DMA转换信号转换成一个完成的回调写TCP流的方法。当然,实际的TCP堆栈要复杂得多。这些句子的东西是如何工作的只是想法。

When you send a byte array to TCP stream, kernel will puts the buffer stream in RAM and control the DMA system to copy the buffer to networking card. When DMA done its job, there is an interrupt inside the CPU invoked. A interrupt handler registered by kernel will transform the signal from DMA into a done callback for write to TCP stream method. Of course, the actual TCP stack is much more complex. These sentences are just idea how the thing works.

有关从TCP流,读出时的软件包来在联网卡的情况下,还有另一种中断调用。该内核通过注册另一个处理程序将改变中断事件上golang身边。

For the case read from TCP stream, when a package come in on networking card, there is another interrupt invoked. The another handler registered by kernel will transform the interrupt to event on golang side.

此外,真正的情况是非常非常复杂的。有很多操作系统,很多版本,许多种IO操作和许多硬件设备。

Again, the real case is very very complex. There are many OSes, many versions, many kind of IO operations and many hardware devices.

这篇关于当执行异步I / O,如何内核确定是否完成了I / O操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆