skynet采用二级队列的方式调度任务。
struct global_queue {
struct message_queue *head;
struct message_queue *tail;
struct spinlock lock;
};
global_queue为第一级,可见队列内容是第二级队列message_queue ,队列操作使用自旋锁,避免频繁的线程上下文切换。
每次调度message_queue ,会根据message_queue 长度一次性的pop多个任务来执行
else if (i==0 && weight >= 0) {
n = skynet_mq_length(q);
n >>= weight;
}
weight为制定的线程权重,前四个是负值。
如果message_queue 为空,则标记in_global=0,不再放入global_queue中,否则重新入队。
如果global_queue为空(实际应用中不会的),message_queue 也不会重新入队,而是直接再次调度,不用再入队出队。
如果global_queue没有任何message_queue 可调度,则
pthread_mutex_lock
pthread_cond_wait
pthread_mutex_unlock
等待唤醒。
加锁
(pthread_cond_wait前要先加锁)
pthread_cond_wait内部会解锁,然后等待条件变量被其它线程激活
(pthread_cond_wait被激活后会再自动加锁)
解锁