今天學習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秒不退出,就認為死循環成立。當然處理方案也只是打印了一個日志罷了。
新聞熱點
疑難解答