同步I / O是否会使线程繁忙?

时间:2019-06-06 00:02:19

标签: sockets linux-kernel posix

假设我正在同步I / O套接字上执行I / O,该套接字已准备好进行readwrite操作。这意味着无论套接字的非阻塞(SOCK_NONBLOCK)/阻塞性质如何,调用线程都不会在操作上被阻塞。但是我不清楚以下事情-

  1. 何时进行实际转移?将套接字标记为可以读取时,内存中是否已经存在数据?或者在调用read命令时传输数据吗?它是否取决于socket的家庭?
  2. 如果在read命令期间执行了数据传输,是否意味着调用线程将繁忙并且延迟取决于套接字硬件?

更新

使用套接字硬件时,我错了,我在考虑下面的实际数据传输。我知道套接字不是问题,而只是OS中的一个实体,它表示适合通信的文件描述符。

后续问题-这也意味着在write期间,调用线程将数据写入内存。是否有一个内核线程将负责在套接字的另一侧传输数据?如果是,那么套接字的异步io与同步io有何不同?

1 个答案:

答案 0 :(得分:2)

通常,您可以将套接字I / O视为两级缓冲系统。您的应用程序中有缓冲区,然后有内核缓冲区。因此,当您调用read()时,内核会将数据从内核缓冲区复制到应用程序缓冲区。相应地,当您调用write()时,您正在将数据从应用程序缓冲区复制到内核缓冲区。

然后,内核告诉NIC将传入数据写入内核缓冲区,并从内核缓冲区读取传出数据。该I / O通常是由DMA驱动的AFAIK,这意味着内核只需要告诉NIC该做什么,而NIC负责实际的数据传输。当NIC完成时,它将引发一个中断(或者,对于高IO速率,将禁用中断,而是由内核轮询),从而导致接收到该中断的CPU内核停止执行正在执行的任何操作(用户代码,内核代码) (除非禁用了中断,否则将在队列中排队)),然后执行中断处理程序,该处理程序将负责其他需要完成的步骤。

因此,为回答您的后续问题,通常在内核侧没有单独的内核线程处理套接字I / O,工作由NIC硬件并在中断上下文中完成。

对于异步I / O或更确切地说是非阻塞I / O,唯一的区别是如何完成从用户应用程序缓冲区和内核缓冲区的复制。对于非阻塞读取,仅将内核缓冲区中准备好并等待的数据复制到用户空间(这可能会导致短读取),或者如果没有数据准备好,则read()调用将立即使用EAGAIN返回。同样,对于非阻塞write(),它仅复制与内核缓冲区中可用空间一样多的数据,这可能会导致写入时间短,或者如果根本没有可用空间,则使用EAGAIN返回。对于阻塞read(),如果没有可用数据,则调用将一直阻塞,直到有可用数据为止;而对于阻塞write(),如果内核缓冲区已满,则它将进行阻塞,直到有可用空间为止。