dsdsm2016 2016-04-08 03:38
浏览 94
已采纳

在执行异步I / O时,内核如何确定I / O操作是否完成?

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

When a goroutine blocks on I/O how does the scheduler identify that it has stopped blocking?

which had the answer

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.


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. Make I/O request such as a GET request to a remote server inside goroutine
  2. Golang makes a syscall to read a TCP stream, which is a blocking operation, but instead of waiting, it asks the kernel to be notified when it's gotten the information. The scheduler removes that blocking goroutine from its queue
  3. When the kernel gets all the information it forwards it to the go process, and lets the scheduler know to add the goroutine back to its queue.

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.

  • 写回答

1条回答 默认 最新

  • dsx58940 2016-04-08 06:59
    关注

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

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

    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.

    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.

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)