​原文​​​​strand​​,​​锁+发送​​队列和​​提交+发送​​队列,哪种方法更好呢?性能说话.答案是​​提交+发送队列>锁+发送队列>strand​​.
​提交​​方法​​连续发送数据​​的另一个好处是,内部​​io​​线程需要​​连续发送数据​​时是无锁的,只有​​提交​​那里有锁,锁的范围很小,同时也影响​​io​​线程发数据的​​效率​​,它的效率无疑是​​最高的​​.
另一个场景,需要发送​​一段数据​​到服务端,数据包括​​包头和包体​​,​​包头​​中有表示​​包体​​长度的​​长度​​字段,​​服务端​​先读​​包头​​解析出​​包体长度​​后再读​​包体​​.客户端这样​​发送数据​​的:

 发送( 负载){
向量<>缓冲;
大小型 大小=负载.大小();
缓冲.调整(大小+4);

复制内存(缓冲.数据(),&大小,4);//包头
复制内存(缓冲.数据()+4,负载.数据(),大小);
//包体.

异步写(异网::缓冲(缓冲));//发送.
}

代码很简单,先构造完整长度的​​缓冲​​​,然后​​拷贝包头​​​,再拷贝​​包体​​​,最后​​发送​​​.这里有个​​问题​​​就是有一​​内存分配​​​(一次是​​负载​​​,一次是​​缓冲​​​)和两次​​内存拷贝​​​,​​性能较低​​​.如何优化性能呢?可用​​零拷贝​​来发送数据.

0拷贝

代码变成:

 发送( 负载){
向量<异网::常缓冲>缓冲;

大小型 大小=负载.大小(); [4];
复制内存(,&大小,4);
缓冲.压后(异网::缓冲(,4));
缓冲.压后(异网::缓冲(负载.数据(),负载.大小()));
异步写(缓冲);
}

这里代码没有​​分配内存​​​,只有一次​​memcpy(head)​​​,效率比之前高很多,这里省掉了​​复制负载​​​,称为​​零拷贝​​​方式发送数据,或者称为​​分散-聚集​​​方式,​​asio​​​提供了发送​​std::vectorasio::常缓冲​​​的接口,​​使用​​​它可实现​​零拷贝​​​方式​​发送数据​​​.
​​​零拷贝​​​底层用​​writev​​​来一次发送多个​​缓冲​​.

虽然​​零拷贝​​​避免了额外​​分配和拷贝​​​内存,但是一次发送多个​​缓冲​​​的效率并没有一次发送大​​缓冲​​​效率高,所以要看​​具体​​​情况,如果是​​小数据​​​,​​分配和拷贝​​​内存代价较小反而比​​零拷贝​​方式更高效.

再改进

避免多次​​分配​​​内存和发送​​多个​​缓冲:

 发送( 负载){
向量<异网::常缓冲>缓冲;

大小型 偏移=4,大小=负载.大小()-偏移;
复制内存(负载.数据(),&大小,4);
异步写(异网::缓冲(负载.数据(),负载.大小()));
}

这里在构造​​负载​​​时候预留出​​包头​​​部分长度,保证​​后面发送​​​时不会再复制​​负载​​​,只​​复制​​​包头很少的数据,同时一次发送​​负载​​,效率更高.