skynet1.0阅读笔记_skynet的启动
首先看skynet的启动,函数入口在 skynet_main.c 的main(),其中最重要的是:
skynet_start(&config);
在skynet_start中做了两个启动:
//启动了snlau服务,然后加载launch服务
bootstrap(ctx, config->bootstrap);
//创建monitor,timer,socket,worker线程等
start(config->thread);
下面我们逐步跟进函数
static void
bootstrap(struct skynet_context * logger, const char * cmdline) {
...
sscanf(cmdline, "%s %s", name, args);
struct skynet_context *ctx = skynet_context_new(name, args);
...
}
这里的cmdline就是 config配置里面的bootstrap那行,默认是为 "snlua bootstrap"
所以实际执行的是 skynet_context_new("snlua","bootstrap")
这里的skynet_context_new是很重要的一个函数,skynet每个lua服务创建,都是使用它来执行的。
skynet_context_new(const char * name="snlua", const char *param="bootstrap") {
//查询mod对象是否已存在,不存在就根据name查找文件加载创建
struct skynet_module * mod = skynet_module_query(name="snlua");
...
//调用mod的create()方法,这里调用了 snlua_create
void *inst = skynet_module_instance_create(mod);
//为lua服务new一个skynet_context的c对象
struct skynet_context * ctx = skynet_malloc(sizeof(*ctx));
...
//为服务的ctx创建一个message_queue
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
//调用对象的init方法,这里是 snlua_init(snlua_create(),ctx,"bootstrap")
int r = skynet_module_instance_init(mod, inst, ctx, param);
if(r==){ //0表示成功
//成功以后,把服务的message_queue放入global_queue全局队列中
skynet_globalmq_push(queue);
}
}
就是说,bootstrap的启动请求 现在交到service_snlua.c的snlua_init里面了,所以接着我们来看snlua_init的实现
snlua_init(struct snlua *l,struct skynet_context *ctx,args="bootstrap"){
...
//把ctx->cb=_launch, ctx->cb是worker线程取出skynet_message时的处理函数
skynet_callback(ctx, l , _launch);
//查询自己的handle id
const char * self = skynet_command(ctx, "REG", NULL);
uint32_t handle_id = strtoul(self+, NULL, );
...
memcpy(tmp, args, sz);
// it must be first message ,然后在这里立即投递第一个请求
skynet_send(ctx, ... , tmp="bootstrap", sz);
...
}
这里需要注意的是,skynet_command这里,实际上通过遍历查找,最终调用了cmd_reg,由于传入的param是NULL,实际是
skynet_command(ctx, "REG", NULL){
sprintf(context->result, ":%x", context->handle);
return context->result;
}
//返回的是自己的ctx的handle id.
也就是下面的skynet_send:
skynet_send(ctx, ... , tmp="bootstrap", sz);
是往自己的队列中投递了一个消息,worker线程拿到这个消息后,根据ctx->cb,调用callback函数: _launch
跟进 _launch:
_launch(..., const void* msg="bootstrap"){
//把context->cb设为NULL了
skynet_callback(context, NULL, NULL);
//_init这里面实际上就是找到要加载的lua文件,然后加载到lua虚拟机中
//在这里就是把 bootstrap.lua文件加在进来
_init(l, context, msg, sz);
...
}
那我们来看看 bootstrap.lua 这个文件
local skynet = require "skynet"
local harbor = require "skynet.harbor"
require "skynet.manager" -- import skynet.launch, ...
local memory = require "memory" skynet.start(function()
...
-- 这里面,使用skynet.newservice 启动了很多个服务 local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher) ... if harbor_id == then
local ok, slave = pcall(skynet.newservice, "cdummy")
skynet.name(".cslave", slave)
else
local ok, slave = pcall(skynet.newservice, "cslave")
skynet.name(".cslave", slave)
end
... if standalone then
local datacenter = skynet.newservice "datacenterd"
skynet.name("DATACENTER", datacenter)
end
...
end)
这里有两点要注意:
1. skynet.start 的function里面,用snlua启动了launcher服务,并用skynet.name把自己注册名字为".launcher"的服务
".launcher" 的调用 skynet.call(".launcher",...)
在后面将经常看到。".launcher"服务就是在这里注册的。
以.开头的名字,是表示这个服务只在当前skynet节点下有效,如果不带点,需要支持跨节点的额外开销,没必要都会带上它。
2.skynet.start 函数
function skynet.start(start_func)
//把回调函数注册为 skynet.dispatch_message
c.callback(skynet.dispatch_message)
//调用 skynet.init_service 调用了外面定义的 function 进行启动
skynet.timeout(, function()
skynet.init_service(start_func)
end)
end
到这里,就能明白,通过skynet_context_new 中的 snlua_init 和
_launch,skynet把请求的处理权从 c交到了 lua手上。
skynet1.0阅读笔记_skynet的启动的更多相关文章
- skynet1.0阅读笔记2_skynet的消息投递skynet.call
为了了解 skynet.call 的调用过程,需要先看看 skynet的队列是如何把包分到不同工作线程的.看下图 查看 global_queue 的skynet_globalmq_push和skyne ...
- The Implementation of Lua 5.0 阅读笔记(一)
没想到Lua的作者理论水平这么高,这篇文章读的我顿生高屋建瓴之感.云风分享了一篇中译:http://www.codingnow.com/2000/download/The%20Implementati ...
- Effective objective-c 2.0阅读笔记
这本书非常的好,看完后,感触挺深,总结纪录一下,针对ios开发的备忘: 注:分类和原著有些不同,自己总结学习用的,仅供参考. 系统篇: 了解oc起源:继承c,由Smalltalk演化而来.动态语言 ...
- The implementation of Lua 5.0 阅读笔记(二)
6 线程和协程 读完这篇文章我才意识到python的协程到底缺了什么,这个就是coroutine和semi-coroutine的区别了.区别就是,semi-coroutine只能返回(yield)到调 ...
- 《C# 6.0 本质论》 阅读笔记
<C# 6.0 本质论> 阅读笔记 阅读笔记不是讲述这本书的内容,只是提取了其中一部分我认为比较重要或者还没有掌握的知识,所以如果有错误或者模糊之处,请指正,谢谢! 对于C# 6.0才 ...
- Linux 0.11源码阅读笔记-文件管理
Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...
- Linux 0.11源码阅读笔记-中断过程
Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...
- Linux 0.11源码阅读笔记-总览
Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...
- Mongodb Manual阅读笔记:CH8 复制集
8 复制 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb Manual阅读笔 ...
随机推荐
- C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数
C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...
- MVC中JSON字符长度超出限制
本文导读:在MVC中通过JsonResult返回JSON字符串时,如果字符串长度过长,会抛出使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错,字符串的长度超过了为 ...
- RHEL6.4 多路径绑定
# rpm -qa | grep mapper #查看multipath是否安装 # lsmod | grep dm_multipath #查看multipath模块是否加载 # rpm -ivh | ...
- 本地PC安装Centos 6.5 操作手册及遇到的问题
我采取的是使用U盘安装 一.准备工作 1.下载Centos6.5 ISO文件 我在官网上下的6.5版本CentOS-6.5-x86_64-bin-DVD1.iso, 由于CentOS-6.5-x86_ ...
- java.lang.IllegalStateException: The specified child already has a parent. You must call removeView
java.lang.IllegalStateException: The specified child already has a parent. You must call removeVi ...
- 解决fonts.googleapis.com不能访问,导致网页打不开
最近,访问linode.com网站,突然发现网速好慢,老是打不开网页.分析一下网页才知道,原来使用了fonts.googleapis.com 打不开的原因就很明显了,咋办呢?百度啊,百度,最后,终于找 ...
- Remoting异步回调,向在线用户广播消息
本文目的:向Remoting在线客户端广播消息. 使用的主要技术:异步,回调,广播. 实现过程: 定义远程实例 using System; using System.Collections.Gener ...
- 【C语言】构造长度可变的二维数组
#include <stdio.h> #include <malloc.h> #include <memory.h> int getArray(int ***p,i ...
- MySQL PLSQL Demo - 001.创建、调用、删除过程
drop procedure if exists p_hello_world; create procedure p_hello_world() begin select sysdate(); end ...
- Maven-7:Maven配置编译的字符集方法
http://blog.csdn.net/jsjszg/article/details/9237189 ************************************************ ...