这是去年在 skynet mailling list 里讨论过的一个话题:skyent中socket中使用共享指针的方式是否有价值? ,今天 review 代码的时候又看到,觉得应该在 blog 记录一下。
简单说就是,当从 skynet 向外部发送相同内容的数据包时,虽然依旧需要一个个包的发送(除非在局域网做 UDP 组播),但在某些特定需求下,复制多份相同的数据包 buffer 是个不必要的开销。
尤其是在上面的帖子中提到的音视频广播的场合,几乎所有的业务都是在向 IO 写同样的数据。所以当时我在考虑后,给 skynet 的 socket 层增加了一个接口,供用户定义共享 buffer ,可以自己在待发送 buffer 对象中自己增加引用计数。
考虑到接口向前兼容,这个用户自定义 buffer 对象的方法要求用户在调用 socket send 时,将 size 设置为 -1 ,以便和 raw 指针区分。
https://github.com/cloudwu/skynet/blob/master/skynet-src/socket_server.h#L56-L63
这样,通过从 C 层面的定制,用户就可以自己实现共享指针了。skynet 的 socket 层会正确的从共享对象里取得指针、取得数据块的大小、以及在使用完毕后释放它。
我没有给出更多的用法范例、也没有给出 lua 封装接口,所以这个 C 接口只提供给了解自己的需求,希望做深度定制的同学去扩展。
如果日后做 MOBA 类游戏,需要大量同步场景中相同的状态信息,或许我会再做一些封装。当然,即使这类场合,我觉得多复制几遍数据,也未必会造成性能问题。