skynet底层源码阅读(4)-服务管理
来源:互联网 发布:淘宝千里眼软件怎么样 编辑:程序博客网 时间:2024/05/22 17:07
在分析skynet的核心的服务代码之前,首先分析一下skynet对多个服务的管理。在Skynet_handle.c中,有:
//实质就是管理一个 skynet_context 的指针数组 ,还有一个handle_name数组struct handle_storage {//读写锁struct rwlock lock;//服务所属 harbor harbor 用于不同主机间通信 uint32_t harbor;//初始值为1,表示handler句柄起始值从1开始uint32_t handle_index;//slot数组的大小 int slot_size;//指针数组,保存skynet_context指针struct skynet_context ** slot;//skynet_context 表空间//handler_name容量,初始为2,这里name_cap与slot_size不一样的原因在于,不是每一个handler都有nameint name_cap;int name_count;//handler_name数量//存放handle_name的数组struct handle_name *name;//handler_name表 数组};//创建全局变量static struct handle_storage *H = NULL;
//handle_name 服务 和对应 handle id的hash表struct handle_name {char * name;//handle是一个uint32_t的整数,高八位表示远程节点(这是框架自带的集群设施,后面的分析都会无视该部分// 一来,他不是框架的核心,二来这个集群设施已经不被推荐使用)uint32_t handle;};简单的说,就是管理了服务结构体指针数组,还有服务对应的名字。skynet中用户可以给服务命名,服务在数组中的位置就是服务的id;之后就是对该容器的操作了,并不复杂
加入服务:
//实质就是将ctx存入到handle_storage维护的一个指针数组中uint32_tskynet_handle_register(struct skynet_context *ctx) {struct handle_storage *s = H;//加写锁rwlock_wlock(&s->lock);for (;;) {int i;//hash选值for (i=0;i<s->slot_size;i++) {//handle是一个uint32_t的整数,高八位表示远程节点(这是框架自带的集群设施,后面的分析都会无视该部分 //#define HANDLE_MASK 0xffffff 就是 00000000 11111111 11111111 11111111 //x&HANDLE_MASK 是将x的高八位变成0uint32_t handle = (i+s->handle_index) & HANDLE_MASK; //等价于handler % s->slot_sizeint hash = handle & (s->slot_size-1);if (s->slot[hash] == NULL) {//找到未使用的 slot 将这个ctx放入到这个slot中 s->slot[hash] = ctx;s->handle_index = handle + 1;//移动 handler_index 方便下次使用rwlock_wunlock(&s->lock);//harbor 用于不同主机之间的通信,handler高8位用于harbor 低24为用于本机的//所以这里要 |=一下handle |= s->harbor;return handle;}}//运行到这里,说明数组满了,//确保扩大 2倍空间之后 总共handler即 slot的数量不超过 24位限制assert((s->slot_size*2 - 1) <= HANDLE_MASK);//哈希表扩大两倍struct skynet_context ** new_slot = skynet_malloc(s->slot_size * 2 * sizeof(struct skynet_context *));memset(new_slot, 0, s->slot_size * 2 * sizeof(struct skynet_context *));//将原来的数据拷贝到新空间for (i=0;i<s->slot_size;i++) {//映射新的hash值int hash = skynet_context_handle(s->slot[i]) & (s->slot_size * 2 - 1);assert(new_slot[hash] == NULL);new_slot[hash] = s->slot[i];}//销毁原来的指针数组skynet_free(s->slot);s->slot = new_slot;s->slot_size *= 2;}}
//根据名称查找handleuint32_t skynet_handle_findname(const char * name) {struct handle_storage *s = H;rwlock_rlock(&s->lock);uint32_t handle = 0;int begin = 0;int end = s->name_count - 1;//这里使用二分查找,听说会有整数溢出,。。。。while (begin<=end) {int mid = (begin+end)/2;struct handle_name *n = &s->name[mid];int c = strcmp(n->name, name);//一直在头部插入,实际这样插入后name会按长度大小排序,这样就能使用二分查找了if (c==0) {handle = n->handle;break;}if (c<0) {begin = mid + 1;} else {end = mid - 1;}}rwlock_runlock(&s->lock);return handle;}
阅读全文
0 0
- skynet底层源码阅读(4)-服务管理
- skynet底层源码阅读(5)-服务
- skynet底层源码阅读(3)-模块管理
- skynet底层源码阅读(1)
- skynet底层源码阅读(2)-消息队列
- skynet底层源码阅读(6)-定时器
- skynet底层源码阅读(7)-网络服务
- skynet底层源码阅读(8)-启动流程
- skynet源码分析【skynet名字的管理】
- skynet源码分析【skynet定时器服务的实现】
- skynet源码分析【skynet服务回调函数的实现】
- skynet源码分析【skynetsnaxd服务的实现】
- ArrayList增删底层源码阅读
- skynet源码学习 - logger服务的工作原理
- skynet源码分析(4)--monitor
- 云风 Skynet 阅读笔记
- Memcache源码阅读(4)---内存管理
- 源码阅读--进程管理
- android 解析XML(Pull、SAX)
- 懂技术懂行业还有力推决心,紫光工业云准备好了
- 运用dtree组件动态生成带复选框的目录树
- pycharm自动添加注释
- java sevlet中使用session,会话跟踪技术
- skynet底层源码阅读(4)-服务管理
- Java:冒泡排序法 和 选择排序
- Mybatis 调用数据库的存储过程
- Android清除缓存功能实现
- sm3算法
- 《Windows核心编程》读书笔记八 用户模式下的内核同步
- 荣之联正式发布大数据平台,这和大多数产品不太一样
- LeetCode----- 20.Valid Parentheses
- 什么是 Zend ? 什么是 PHP ?