skynet启动过程_1
int
main(int argc, char *argv[]) {
const char * config_file = NULL ;
if (argc > ) {
config_file = argv[];
} else {
fprintf(stderr, "Need a config file. Please read skynet wiki : https://github.com/cloudwu/skynet/wiki/Config\n"
"usage: skynet configfilename\n");
return ;
}
skynet_globalinit();
skynet_env_init(); sigign(); struct skynet_config config; struct lua_State *L = lua_newstate(skynet_lalloc, NULL);
luaL_openlibs(L); // link lua lib int err = luaL_loadstring(L, load_config);
assert(err == LUA_OK);
lua_pushstring(L, config_file); err = lua_pcall(L, , , );
if (err) {
fprintf(stderr,"%s\n",lua_tostring(L,-));
lua_close(L);
return ;
}
_init_env(L); config.thread = optint("thread",);
config.module_path = optstring("cpath","./cservice/?.so");
config.harbor = optint("harbor", );
config.bootstrap = optstring("bootstrap","snlua bootstrap");
config.daemon = optstring("daemon", NULL);
config.logger = optstring("logger", NULL); lua_close(L); skynet_start(&config);
skynet_globalexit(); return ;
}
配置了一些基本的环境变量后,转到skynet_start方法,开始启动skynet,在skynet_start方法中初始化一些变量后,系统启动的第一个服务是logger:
struct skynet_context *ctx = skynet_context_new("logger", config->logger);
if (ctx == NULL) {
fprintf(stderr, "Can't launch logger service\n");
exit();
}
struct skynet_module * mod = skynet_module_query(name);
if (mod == NULL)
return NULL;
void *inst = skynet_module_instance_create(mod);
ctx->handle = skynet_handle_register(ctx);
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
int r = skynet_module_instance_init(mod, inst, ctx, param);
skynet_globalmq_push(queue);
启动完成logger服务后,系统接下来要启动的服务是bootstrap,但先要加载snlua模块,所有的lua服务都属于snlua模块的实例。
static void
bootstrap(struct skynet_context * logger, const char * cmdline) {
int sz = strlen(cmdline);
char name[sz+];
char args[sz+];
sscanf(cmdline, "%s %s", name, args);
struct skynet_context *ctx = skynet_context_new(name, args);
if (ctx == NULL) {
skynet_error(NULL, "Bootstrap error : %s\n", cmdline);
skynet_context_dispatchall(logger);
exit();
}
}
struct snlua *
snlua_create(void) {
struct snlua * l = skynet_malloc(sizeof(*l));
memset(l,,sizeof(*l));
l->L = lua_newstate(skynet_lalloc, NULL);
return l;
}
int
snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
int sz = strlen(args);
char * tmp = skynet_malloc(sz);
memcpy(tmp, args, sz);
skynet_callback(ctx, l , _launch);
const char * self = skynet_command(ctx, "REG", NULL);
uint32_t handle_id = strtoul(self+, NULL, );
// it must be first message
skynet_send(ctx, , handle_id, PTYPE_TAG_DONTCOPY,, tmp, sz);
return ;
}
static int
_launch(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) {
assert(type == && session == );
struct snlua *l = ud;
skynet_callback(context, NULL, NULL);
int err = _init(l, context, msg, sz);
if (err) {
skynet_command(context, "EXIT", NULL);
} return ;
}
local skynet = require "skynet"
local harbor = require "skynet.harbor" skynet.start(function()
local standalone = skynet.getenv "standalone" local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher) local harbor_id = tonumber(skynet.getenv "harbor")
if harbor_id == then
assert(standalone == nil)
standalone = true
skynet.setenv("standalone", "true") local ok, slave = pcall(skynet.newservice, "cdummy")
if not ok then
skynet.abort()
end
skynet.name(".cslave", slave) else
if standalone then
if not pcall(skynet.newservice,"cmaster") then
skynet.abort()
end
end local ok, slave = pcall(skynet.newservice, "cslave")
if not ok then
skynet.abort()
end
skynet.name(".cslave", slave)
end if standalone then
local datacenter = skynet.newservice "datacenterd"
skynet.name("DATACENTER", datacenter)
end
skynet.newservice "service_mgr"
pcall(skynet.newservice,skynet.getenv "start" or "main")
skynet.exit()
end)
在这个文件里启动了其它一些服务,这些暂不看,在这个文件里调用了服务启动的接口skynet.start。这也是所有lua服务的标准启动入口,参数是一个回调方法,服务启动完成后会调到这个方法。做一些初始化的工作。
function skynet.start(start_func)
c.callback(dispatch_message)
skynet.timeout(, function()
init_service(start_func)
end)
end
static int
_callback(lua_State *L) {
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex());
int forward = lua_toboolean(L, );
luaL_checktype(L,,LUA_TFUNCTION);
lua_settop(L,);
lua_rawsetp(L, LUA_REGISTRYINDEX, _cb); lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
lua_State *gL = lua_tothread(L,-); if (forward) {
skynet_callback(context, gL, forward_cb);
} else {
skynet_callback(context, gL, _cb);
} return ;
}
skynet启动过程_1的更多相关文章
- skynet启动过程_bootstrap
这遍摘自skynet 的wiki skynet 由一个或多个进程构成,每个进程被称为一个 skynet 节点.本文描述了 skynet 节点的启动流程. skynet 节点通过运行 skynet 主程 ...
- zookeeper源码分析之一服务端启动过程
zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- Openfire的启动过程与session管理
说明 本文源码基于Openfire4.0.2. Openfire的启动 Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...
- 探索 Linux 系统的启动过程
引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...
- Linux内核启动过程概述
版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...
- SpringMVC启动过程详解(li)
通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...
- Android源码——Activity组件的启动过程
根Activity启动过程 Launcher启动MainActivity的过程主要分为6个步骤: 一.Launcher向ActivityManagerService发送一个启动MainActivity ...
- Netty源码分析之客户端启动过程
一.先来看一下客户端示例代码. public class NettyClientTest { public void connect(int port, String host) throws Exc ...
随机推荐
- BZOJ_3039_玉蟾宫_(动态规划+悬线法)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3039 n*m的矩阵由R和F组成,求全是F的子矩阵的大小的三倍. 分析 悬线法: 浅谈用极大化思 ...
- PHPCMS 2008 SQL注入漏洞
漏洞版本: PHPCMS 2008 漏洞描述: escape()方法无法过滤$genre变量进行二次URL编码,导致SQL注入漏洞产生. <* 参考 http://www.yunsec.net/ ...
- SCOI2005互不侵犯King
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1499 Solved: 872[Submit][S ...
- JDK/bin目录下的不同exe文件的用途(转)
新安装完JDk 大家是否发现安装目录的bin文件夹有很多exe文件 下面就为大家讲解不同exe文件的用途 javac:Java编译器,将Java源代码换成字节代 java:Java解释器,直接从类文件 ...
- EMC
1.EMC的概念 EMC(Electro Magnetic Compatibility)即电磁兼容,是指设备或系统在其电磁环境中符合要求运行并不对其环境中的任何设备产生无法忍受的电磁干扰的能力.就是它 ...
- Unity 打包后文件系统访问的一个小细节
Android: 使用 File 类 来访文本文件系统不区分大小写:但是访问 jar 包内的文件是区分大小写的,比如使用 www类,都需要区分大小写. iOS: 使用 File 类 来访文本文件系统严 ...
- HW3.10
public class Solution { public static void main(String[] args) { int number1 = (int)(Math.random() * ...
- storm-starter项目概述
storm-starter项目包含使用storm的各种各样的例子.项目托管在GitHub上面,其网址为: http://github.com/nathanmarz/storm-starter stor ...
- 浅谈js观察者模式
观察者模式又叫发布订阅模式,它可以让多个观察者对象同时监听某一个主题对象,即在一个事件发生时,不同的对象迅速对其进行相应.就比如当又人闯红灯,不同的人对这件事迅速发起响应,当然这个比喻不太恰当,不过在 ...
- 恼人的Visual Studio 2010崩溃重启问题
上周时Visual Studio 2010突然出现崩溃现象.在源文件修改只要一编译,马上就崩溃,而且还不弹出任何异常窗口,严重影响软件开发工作. google了无数解决方案 试了下面这些方法: 1)h ...