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 ...
随机推荐
- ☀【CSS3】切换开关
采用纯 CSS3 制作 iPhone 风格切换开关 √http://5m3d.com/?p=846 <!DOCTYPE html> <html lang="zh-CN&qu ...
- seleniumRC启动及浏览器实例配置
一.firefox浏览器实例配置 1.启动用户配置文件管理器 重要:在启动用户配置文件管理器之前,Firefox必须完全关闭. 1)按 support.cdn.mozilla.net/medi ...
- 2015年10月16日HTML标签表单笔记
textarea只是纯文本编辑框,要想输入各种样式的文本.图片.表格等需要使用“富文本编辑框”.html4暂无富文本编辑框,可使用第三方工具实现此效果. <textarea></te ...
- MTRR内存类型范围寄存器
1.MTRR的概念 内存类型范围寄存器(MTRRs,翻译过来真别扭,后面都以MTRR直接来说了)提供了一种机制,这种机制其实就是确定在系统内存中物理一段内存的类型.这个类型其实是正对CPU来说的,见图 ...
- ACM2030_机内码
/* 汉字统计 问题说明 统计给定文本文件中汉字的个数. 输入 输入文件首先包含一个整数Ñ,表示测试实例的个数,然后是Ñ段文本. 产量 对于每一段文本,输出其中的汉字的个数,每个测试实例的输出 ...
- 【原创】Mac上编译Hadoop1.0.3出现的一些问题
create-native-configure: [exec] configure.ac:47: error: possibly undefined macro: AC_PROG_LIBTOOL [e ...
- 教程-Delphi MSComm 实时串口通讯
Delphi MSComm 实时串口通讯 MSComm控件具有丰富的与串口通信密切相关的属性,提供了对串口进行的多种操作,进而使串行通信变得十分简便.MSComm的控件属性较多,常用的属性如下:1) ...
- hdoj 1977 Consecutive sum II
Consecutive sum II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- jquery实时监听某个文本框的输入事件
想给页面的的一个文本框添加监听事件 $(function(){ //页面加载完毕后触发事件 $("textarea[name='content']").bind('input pr ...
- csdn 刷分小工具(刷了1000多被封了,慎用)
先上图,周第一, 月第六代码未整理,比较乱,仅仅供参考(cookie已经废了,号被封了,哈哈) using System; using System.Collections.Generic; usin ...