作者:shihuaping0918@163.com,转载请注明作者
消息机制是skynet中一个比较难理解的东西,在开始分析代码前,建议先读一下云风的博客和skynet的WIKI。SKYNET设计综述:http://blog.codingnow.com/2012/09/the_design_of_skynet.html,CLUSTER:https://github.com/cloudwu/skynet/wiki/Cluster。
SKYNET设计综述讲到模块被称为服务。“服务间可以自由发送消息。每个模块可以向 Skynet 框架注册一个 callback 函数,用来接收发给它的消息。”还提到“把一个符合规范的 C 模块,从动态库(so 文件)中启动起来,绑定一个永不重复(即使模块退出)的数字 id 做为其 handle 。Skynet 提供了名字服务,还可以给特定的服务起一个易读的名字,而不是用 id 来指代它。id 和运行时态相关,无法保证每次启动服务,都有一致的 id ,但名字可以。”今天要分析的两个文件skynet_handle.c和skynet_handle.h就是实现名字服务的。
而WIKI中的CLUSTER讲到的是harbor相关的内容,“每个 skynet 服务都有一个全网唯一的地址,这个地址是一个 32bit 数字,其高 8bit 标识着它所属 slave 的号码。即 harbor id 。在 master/slave 网络中,id 为 0 是保留的。所以最多可以有 255 个 slave 节点。”
前面写这么一大段东西都是分析代码所需要的,不是为了凑字数,也不是为了别的原因。下面开始分析代码。
#include "skynet.h"
#define DEFAULT_SLOT_SIZE 4
#define MAX_SLOT_SIZE 0x40000000
//名字服务结构,一个名字对应一个handle
struct handle_name {
char * name; //服务名字
uint32_t handle; //服务ID,下面以handle来称呼
};
//保存handle/name列表的数据结构,skynet_handle_init会初始化它
struct handle_storage {
struct rwlock lock;
uint32_t harbor;//这就是wiki里提到的harbor!!
uint32_t handle_index; //必须从1开始
int slot_size; //数组长度
struct skynet_context ** slot; //数组,实际上里面存的是服务的上下文
int name_cap; //容量
int name_count; //长度或者说个数
struct handle_name *name; //数组
};
static struct handle_storage *H = NULL;
//注册服务,返回给它一个handle
uint32_t
skynet_handle_register(struct skynet_context *ctx) {
struct handle_storage *s = H;
rwlock_wlock(&s->lock);
//死循环,所以服务数量如果太大了你懂得
for (;;) {
int i;