这种客户端-服务器通信方式如何节省两次内核交叉?

How can this client-server communication method save two kernel crossings?

在一本 OS 书中,当谈到客户端-服务器通信时,它说:

Client-server communication is a common pattern in many systems, and so one can ask: how can we improve its performance? One step is to recognize that both the client and the server issue a write immediately followed by a read, to wait for the other side to reply; at the cost of adding a system call, these can be combined to eliminate two kernel crossings per round trip.

我想知道“立即发出写入并紧接着读取”如何在每次往返中节省 2 个内核交叉。

A write 向内核发出系统调用,导致内核从用户模式切换到内核模式。当 write 完成后, OS returns 到用户代码,从内核模式到用户模式。

然后,read被调用,导致内核从用户模式到内核模式,然后它returns到用户代码,从内核模式到用户模式。

那么什么是saved内核交叉呢?是不是说write完成后,不return到用户代码和用户态,而是直接read在内核态运行?

就OS书上的理解而言,这是一个潜在的优化。 OS 可能有一个同时写入和读取的系统调用。它可能是一个假设的系统调用,例如 int write_read(int fd, char *write_buf, size_t write_len, char *read_buf, size_t *read_len)。但是linux内核没有这样的调用。

现代内核不为系统调用使用中断,因此优化不会有太大帮助。此外,对性能至关重要的现代应用程序通常使用某种异步 non-blocking 处理,因此建议的优化对它们来说无论如何都是无用的。该优化的进一步问题是错误报告。如果出现故障,调用者将无法轻易识别是读取失败还是写入失败。