monitor
monitor分为服务器的monitor 和 skynet_monitor,整个服务器只有一个服务器monitor,每条工作线程绑定一个skynet_monitor,上面在声明了若干条线程数量后,先做的就是创建服务器monitor。
服务器 monitor
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
| struct monitor { int count; struct skynet_monitor ** m; pthread_cond_t cond; pthread_mutex_t mutex; int sleep; int quit; };
start(int thread) { ... 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(); } if (pthread_mutex_init(&m->mutex, NULL)) { fprintf(stderr, "Init mutex error"); exit(1); } if (pthread_cond_init(&m->cond, NULL)) { fprintf(stderr, "Init cond error"); exit(1); } create_thread(&pid[0], thread_monitor, m); ... }
|
工作线程监视 skynet_monitor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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 *);
struct skynet_monitor { int version; int check_version; uint32_t source; uint32_t destination; };
truct skynet_monitor * skynet_monitor_new() { struct skynet_monitor * ret = skynet_malloc(sizeof(*ret)); memset(ret, 0, sizeof(*ret)); return ret; }
|
thread_monitor 线程
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #define CHECK_ABORT if (skynet_context_total()==0) break;
void skynet_initthread(int m) { uintptr_t v = (uint32_t)(-m); pthread_setspecific(G_NODE.handle_key, (void *)v); }
void skynet_monitor_check(struct skynet_monitor *sm) { if (sm->version == sm->check_version) { if (sm->destination) { skynet_context_endless(sm->destination); skynet_error(NULL, "A message from [ :%08x ] to [ :%08x ] maybe in an endless loop (version = %d)", sm->source , sm->destination, sm->version); } } else { sm->check_version = sm->version; } }
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; }
|
至此,skynet.star大概做了什么,monitor部分功能都做了大概分析。下篇顺着skynet.star分析,thread_timer(skynet定时器)