zoukankan      html  css  js  c++  java
  • skynet源代码学习


    当skynet启动的时候,会依据配置文件制定的日志文件来创建一个logger context。详细过程就是找到logger.so动态链接文件。而后调用其logger_create函数(參数是配置的日志文件),而后构建这个服务相应的context(重要的是里面注冊了该服务的回调函数_logger())和消息队列,最后运行logger_init函数。把logger的消息队列放入global queue.关键代码例如以下:
    handle = skynet_handle_register(ctx);    // 注冊得到一个服务句柄
    	struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
    	// init function maybe use ctx->handle, so it must init at last
    	context_inc();    // 这个skynet节点服务数加1
    
    	CHECKCALLING_BEGIN(ctx)
    	int r = skynet_module_instance_init(mod, inst, ctx, param);
    	CHECKCALLING_END(ctx)
    	if (r == 0) {
    		// xxx_init 成功返回。刚才的 ref-1 = 1
    		struct skynet_context * ret = skynet_context_release(ctx);
    		if (ret) {
    			ctx->init = true;  // 初始化成功
    		}
    		// 放入全局消息队列,能够接受其它服务的消息
    		skynet_globalmq_push(queue);
    		if (ret) {
    			skynet_error(ret, "LAUNCH %s %s", name, param ?

    param : ""); } return ret; } else { skynet_error(ctx, "FAILED launch %s", name); uint32_t handle = ctx->handle; skynet_context_release(ctx); skynet_handle_retire(handle); struct drop_t d = { handle }; skynet_mq_release(queue, drop_message, &d); return NULL; }




    代码中错误处理中的skynet_error() 就是日志输出函数,会将错误字符串构造为一个skynet_mssage,放入到logger的消息队列中。msg中会保存消息的来源handle。关键代码例如以下:
    struct skynet_message smsg;
    	if (context == NULL) {
    		smsg.source = 0;
    	} else {
    		// msg source 是ctx的handle号
    		smsg.source = skynet_context_handle(context);
    	}
    	smsg.session = 0;
    	smsg.data = data;
    	// sz低24位保存的是数据大小
    	smsg.sz = len | (PTYPE_TEXT << HANDLE_REMOTE_SHIFT);
    	// 把这个消息放到logger的队列中
    	skynet_context_push(logger, &smsg);




    那些消息何时输出呢?skynet启动时会新起一定的worker线程,它们的工作就是消费这些消息,运行相应的回调函数,对于logger来说就是把信息输出到相应的文件句柄中。代码例如以下:
    static void
    _dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
    	assert(ctx->init);
    	CHECKCALLING_BEGIN(ctx)
    	pthread_setspecific(G_NODE.handle_key, (void *)(uintptr_t)(ctx->handle));
    	int type = msg->sz >> HANDLE_REMOTE_SHIFT;
    	size_t sz = msg->sz & HANDLE_MASK;
    	// 运行节点的回调接口_cb
    	if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) {
    		skynet_free(msg->data);
    	} 
    	CHECKCALLING_END(ctx)
    }







    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    javascript定时器,取消定时器,及js定时器优化方法
    Systen,IO
    批量地理位置解析
    数据库分区分表(sql、mysql)
    数据库还原的多种方式
    js前端文件收集(一)
    NPOI解决由于excel删除数据导致空行读取问题
    echarts2.0tooltip边框限制导致tooltip显示不全解决办法
    数据库备份通用脚本
    echarts 用marlkline画线 同时配置中含有datazoom,怎么设置markline
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4836083.html
Copyright © 2011-2022 走看看