# 一、介绍 管道是由客户端提供的一种加快存取效率的技术。 如图所示,客户端将请求发给服务器,需要进过2个操作写->读,如果是多个操作就变成写->读->写->读 ![[Snipaste_2023-02-24_09-52-40 1.png]] 此时如果调整读写顺序,变成写->写->读->读,两个连续的写操作和两个连续的读操作总共只会花费一次网络来回。 管道的本质就是改变读写操作顺序来节省IO时间。管道中指令越多效果越好。 # 二、管道原理 ![[Snipaste_2023-02-24_09-52-40 2.png]] 1. 客户段进程调用write将消息写到socket的send buffer中 2. 客户端操作系统将发送缓冲的内容发送到网卡,网卡将数据通过路由送到服务器网卡 3. 服务器操作系统将网卡内容放到socket的recv buffer中 4. 服务器进程调用read从接收缓冲中读取消息进行处理 5. 服务器进程调用write将响应消息写入到socket的send buffer中 6. 服务器操作系统将发送缓冲的内容发送到网卡,网卡将数据通过路由送到客户端网卡 7. 客户端器操作系统将网卡内容放到socket的recv buffer中 8. 客户端进程调用read从接收缓冲中读取消息进行处理 9. 结束 5~8和1~4步骤一样,方向不同。一个是请求,一个是响应。 重点:write操作只负责将数据写到send buffer就返回了,剩下的事情由操作系统处理。对于redis.get(key)来说,write操作几乎没有耗时,直接写到发送缓冲就返回,而read需要走完上述的流程。 对于管道来说,连续的write操作根本没有耗时,之后的第一个read操作会等待一个网络的来回开销,然后所有的响应消息就已经回到了recv buffer,后续的read操作就直接从recv buffer拿结果即可。 如果send buffer满了,那么就需要等待缓冲空出空间来,这就是写操作IO的真正耗时。