Skynet基本概况
工作流程
主要工作流程图

上图中所示的每个队列都关联一个服务的。所有的队列连接成一个大链表。
一个工作线程主要工作流程:
1 2 3 4 5 6 7
| while(true) { queue = get_one_queue(global_queue) ctx = get_ctx( queue->handle ) msg = get_one_message(queue) ctx->callback(msg) }
|
一个skynet节点,也就是一个skynet进程。它启动的时候会创建多个线程:
- 网络线程:
- 接收skynet外部的网络请求,然后push到服务的队列。
- 当服务需要把数据发送给外部时,实质上是 服务—>网络线程—>外部
- 定时器线程:把定时器消息push到某个服务。当服务在处理定时器消息时,就可以认为是定时器事件触发了。
- 监听线程:主要是发现工作线程有没有死循环。
- 工作线程:驱动服务处理消息
主函数代码
skynet_main函数
main函数读取了一个 lua配置文件。这个配置文件就是启动 skynet进程时使用的命令,类似 ./skynet config 。 这里的config就是配置文件。Skynet_Config官方文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| int main(int argc, char *argv[]) { const char * config_file = NULL ; skynet_globalinit(); skynet_env_init();
sigign();
struct skynet_config config;
struct lua_State *L = luaL_newstate(); luaL_openlibs(L);
int err = luaL_loadbufferx(L, load_config, strlen(load_config), "=[skynet config]", "t"); assert(err == LUA_OK); lua_pushstring(L, config_file);
err = lua_pcall(L, 1, 1, 0);
_init_env(L); config.thread = optint("thread",8); config.module_path = optstring("cpath","./cservice/?.so"); config.harbor = optint("harbor", 1); config.bootstrap = optstring("bootstrap","snlua bootstrap"); config.daemon = optstring("daemon", NULL); config.logger = optstring("logger", NULL); config.logservice = optstring("logservice", "logger"); config.profile = optboolean("profile", 1);
lua_close(L);
skynet_start(&config); skynet_globalexit();
return 0; }
|
skynet_start函数
初始化工作和启动两个服务——bootstrap(ctx, config->bootstrap) 和 start(config->thread)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void skynet_start(struct skynet_config * config) {
skynet_harbor_init(config->harbor); skynet_handle_init(config->harbor); skynet_mq_init(); skynet_module_init(config->module_path); skynet_timer_init(); skynet_socket_init();
skynet_profile_enable(config->profile); struct skynet_context *ctx = skynet_context_new(config->logservice, config->logger);
skynet_handle_namehandle(skynet_context_handle(ctx), "logger");
bootstrap(ctx, config->bootstrap); start(config->thread); }
|
start函数
启动:监听线程、定时器线程、网络线程和多个工作线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| static void start(int thread) { pthread_t pid[thread+3];
struct monitor *m = skynet_malloc(sizeof(*m)); memset(m, 0, sizeof(*m)); m->count = thread; m->sleep = 0;
m->m = skynet_malloc(thread * sizeof(struct skynet_monitor *)); int i; for (i=0;i<thread;i++) { m->m[i] = skynet_monitor_new(); } create_thread(&pid[0], thread_monitor, m); create_thread(&pid[1], thread_timer, m); create_thread(&pid[2], thread_socket, m);
struct worker_parm wp[thread]; for (i=0;i<thread;i++) { create_thread(&pid[i+3], thread_worker, &wp[i]); } }
|


Barbecue
今天学习了吗
此文章版权归Barbeuce所有,如有转载,请注明明来自原作者