将数据从内核复制到用户期间,非阻塞 I/O 是否会进入休眠状态?

我问这个问题是因为我正在研究 Go 中的多路 I/O,它使用epollwait.

当套接字准备好时,goroutine 将被唤醒并开始以非阻塞模式读取套接字。如果read在将数据从内核复制到用户的过程中系统调用仍然会被阻塞,我假设 gorouine 附加的内核线程也将进入睡眠状态。

我对此不太确定,如果我错了,希望有人能帮助纠正我。


素胚勾勒不出你
浏览 107回答 1
1回答

慕莱坞森

我无法完全解析你所写的内容。我将尝试进行纯粹的猜测并想象您可能正在监督这样一个事实:置于非阻塞模式的write(2)套接字上的和read(2)系统调用(以及它们的同类,例如send(2)和)可以自由使用(分别返回)数据少于请求的数据。 换句话说,对非阻塞套接字的调用被告知要写入 1 MB 数据,将消耗与当前适合关联的内核缓冲区的数据一样多的数据,并立即返回,表明它只消耗了同样多的数据。下一次立即调用可能会返回。recv(2)write(2)write(2)EWOULDBLOCK调用也是如此read(2):如果您向其传递一个足以容纳 1 MB 数据的缓冲区,并告诉它读取该数量的字节,则该调用只会耗尽内核缓冲区的内容并立即返回,并指示有多少字节。它实际复制的数据。下一次立即调用read(2)可能会返回EWOULDBLOCK。因此,任何获取数据或将数据放入套接字的尝试几乎都会立即成功:要么在数据被铲入内核缓冲区和用户空间之间之后,要么立即返回代码EAGAIN。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go