很多人解读libuv,每个人侧重点则不同,最近看了看libuv源码,从用户线程的调度过程来解读下libuv,以下解读如有不正确,也请指正(前提:从linux角度读libuv源码)
此处列举下面要解答的问题:
1,libuv在线程间传递消息采用的什么机制
2,libuv创建的工作线程会不会在执行完用户任务后退出
3,libuv从接收任务到将任务发送给工作线程,是怎么个实现过程
4,工作线程执行完毕后,调用的work done是如何被执行的
1,libuv把任务发送给用户工作线程时,使用的是条件变量通知
static void post(QUEUE* q, enum uv__work_kind kind) {
uv_mutex_lock(&mutex);
if (kind == UV__WORK_SLOW_IO) {
/* Insert into a separate queue. */
QUEUE_INSERT_TAIL(&slow_io_pending_wq, q);
if (!QUEUE_EMPTY(&run_slow_work_message)) {
/* Running slow I/O tasks is already scheduled => Nothing to do here.
The worker that runs said other task will schedule this one as well. */
uv_mutex_unlock(&mutex);
return;
}
q = &run_slow_work_message;
}
QUEUE_INSERT_TAIL(&wq, q); //将任务插入工作队列
if (idle_threads > 0)
uv_cond_signal(&cond); //此处即为给用户工作线程发送条件变量通知消息
uv_mutex_unlock(&mutex);
}
2,通常情况下,libuv创建的4个默认工作线程不会退出
3,libuv将任务发送给用户工作线程,用户工作线程通过条件变量唤醒,然后从工作队列中取出一个任务,并调用用户设定的实际处理函数,来处理具体业务
static void worker(void* arg) {
struct uv__work* w;
QUEUE* q;
int is_slow_work;
uv_sem_post((uv_sem_t*) arg); //通知主线程:工作线程已启动
arg = NULL;
uv_mutex_lock(&mutex);
for (;;) {
/* `mutex` should always be locked at this point. */
/* Keep waiting while either no work is present or only slow I/O
and we're at the threshold for that. */
while