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

问题描述 投票:0回答:1

我问这个问题,因为我正在寻找使用epollwait的Go中的多路复用I / O。

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

我不确定,如果我错了,希望有人可以帮助纠正我。

linux go io linux-kernel nonblocking
1个回答
0
投票
[我将尽力猜测并让人联想到您可能忽略了以下事实:在插槽中插入了write(2)read(2)系统调用(以及它们类似的系统调用,例如send(2)recv(2)

非阻塞模式可以自由消耗(并分别返回)少于请求的数据。换句话说,在非阻塞套接字上的write(2)调用被告知要写入1兆字节的数据,将消耗与关联的内核缓冲区中当前可容纳的数据相同的数量,并立即返回,表示仅消耗了相同的数据。下一次立即调用write(2)可能会返回EWOULDBLOCK

read(2)调用也是如此:如果向它传递一个足以容纳1兆字节数据的缓冲区,并告诉它读取该字节数,则该调用只会耗尽内核缓冲区的内容并返回立即发出信号,说明实际复制了多少数据。下一次立即调用read(2)可能会返回EWOULDBLOCK

因此,任何将数据获取或放入套接字的尝试几乎都立即成功:在将数据铲入内核的缓冲区和用户空间之间之后,或者立即使用EAGAIN返回代码。

当然,在执行此类syscall的过程中,可能存在OS线程被挂起的可能性,但这不算作“阻塞

in

syscall。”
© www.soinside.com 2019 - 2024. All rights reserved.