今天学习skynet_monitor。
skynet_monitor主要用于监测skynet_context在处理消息时是否陷入死循环。
struct skynet_monitor;struct skynet_monitor * skynet_monitor_new();//新建一个监视器void skynet_monitor_delete(struct skynet_monitor *);//删除一个监视器void skynet_monitor_trigger(struct skynet_monitor *, uint32_t source, uint32_t destination);//通知监视器开始void skynet_monitor_check(struct skynet_monitor *);//检查监视器是否陷入死循环skynet启动时会为每个工作线程创建一个对应的监视器:static voidstart(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();//创建监视器 } ......然后,sc在处理消息时,会调用skynet_monitor_trigger:struct message_queue * skynet_context_message_dispatch(struct skynet_monitor *sm, struct message_queue *q, int weight) { ...... ...... for (i=0;i<n;i++) { ...... ...... skynet_monitor_trigger(sm, msg.source , handle);//开始监视 if (ctx->cb == NULL) { skynet_free(msg.data); } else { dispatch_message(ctx, &msg);//处理消息 } skynet_monitor_trigger(sm, 0,0);//结束监视 } ...... return q;}监视的驱动是由一个单独的线程来做的:static void *thread_monitor(void *p) { struct monitor * m = p; int i; int n = m->count; skynet_initthread(THREAD_MONITOR); for (;;) { CHECK_ABORT for (i=0;i<n;i++) { skynet_monitor_check(m->m[i]); } for (i=0;i<5;i++) { CHECK_ABORT sleep(1); } } return NULL;}从这里可以看出,5秒不退出,就认为死循环成立。当然处理方案也只是打印了一个日志罢了。
新闻热点
疑难解答