Read the skynet source code from the beginning (1) What does the main entrance do

       I have been using skynet for a year and a half. I have read a lot of source code intermittently, and read a few skynet source code analysis. They all said very well. But I think the analysis is just to give you a point of understanding the code, but no one has a different way of understanding. I also write my own understanding.

       Enter the topic below.

       First of all, we still have to have an idea, what does skynet do, the overview of Skynet design by the predecessors of Yunfeng, and the wiki are all to be read. Then enter the topic.

       From the beginning of my study, a C/C++ program I understand is run from the main function, and skynet is no exception. The following key parts of the code are commented.

skynet_main.c   

The main function is actually to parse the configuration, do some initialization, and then use the configuration to call the startup function.

int
main(int argc, char *argv[]) {
	const char * config_file = NULL ;
	if (argc > 1) {
		config_file = argv[1];
	} else {
		fprintf(stderr, "Need a config file. Please read skynet wiki : https://github.com/cloudwu/skynet/wiki/Config\n"
			"usage: skynet configfilename\n");
		return 1;
	}

	//这里做一些初始化
	luaS_initshr();
	skynet_globalinit();
	skynet_env_init();

	sigign();

	struct skynet_config config;

	//打开一个lua虚拟机用于解析传入的配置
	struct lua_State *L = luaL_newstate();	
	luaL_openlibs(L);	// link lua lib

	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);
	if (err) {
		fprintf(stderr,"%s\n",lua_tostring(L,-1));
		lua_close(L);
		return 1;
	}
	_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虚拟机
	lua_close(L);

	//通过配置启动调用skynet_start
	skynet_start(&config);
	skynet_globalexit();
	luaS_exitshr();

	return 0;
}

skynet_start.c

What skynet_start does is continue to initialize. What needs to be noted here is bootstrap. Here you can know through configuration. In fact, snlua (a module written in C) is started. After that, all lua services are started through snlua (snlua loads lua files) )) Remember first, then analyze.

void 
skynet_start(struct skynet_config * config) {
	// register SIGHUP for log file reopen
	// 这里处理一些信号的问题。
	struct sigaction sa;
	sa.sa_handler = &handle_hup;
	sa.sa_flags = SA_RESTART;
	sigfillset(&sa.sa_mask);
	sigaction(SIGHUP, &sa, NULL);

	//看看是否配置了守护进程
	if (config->daemon) {
		if (daemon_init(config->daemon)) {
			exit(1);
		}
	}
	skynet_harbor_init(config->harbor);			// harbor(港口)初始化
	skynet_handle_init(config->harbor);			// handler初始化,存贮全部的服务句柄
	skynet_mq_init();							// 全局队列初始化
	skynet_module_init(config->module_path);	// C模块初始化
	skynet_timer_init();						// 定时器初始化
	skynet_socket_init();						// socket初始化
	skynet_profile_enable(config->profile);		

	//启动logger服务
	struct skynet_context *ctx = skynet_context_new(config->logservice, config->logger);
	if (ctx == NULL) {
		fprintf(stderr, "Can't launch %s service\n", config->logservice);
		exit(1);
	}

	skynet_handle_namehandle(skynet_context_handle(ctx), "logger");

	//启动配置中的bootstrap服务
	bootstrap(ctx, config->bootstrap);

	//调用start传入配置线程数量
	start(config->thread);

	// harbor_exit may call socket send, so it should exit before socket_free
	skynet_harbor_exit();
	skynet_socket_free();
	if (config->daemon) {
		daemon_exit(config->daemon);
	}
}

Then call, start, which is the start of the whole logic, the next article first analyzes bootstrap.

Guess you like

Origin blog.csdn.net/banfushen007/article/details/109262729