1、说明

libuv 提供了一个线程池,可用于运行用户代码,libuv 中的工作队列中的任务会在线程池中执行

libuv 中的线程池在内部用于运行所有文件系统操作以及 getaddrinfo()getnameinfo() 请求

libuv 中的线程池的默认数量为4,可以在启动时修改环境变量 UV_THREADPOOL_SIZE 来修改,最大值为 1024(1.30.0版本之前是128)

libuv 中的线程池是全局的,并在所有事件循环之间共享,当特定的函数利用 uv_queue_work() 方法使用工作队列时,libuv 会预分配线程池,以较小的内存开销(128个线程为1MB),来提高线程性能

以下三种类型的操作会在全局线程池中进行:

  1. 文件系统操作;
  2. DNS函数(getaddrinfo 和 getnameinfo);
  3. 使用 uv_queue_work() 调度的用户代码;

需要注意的是,即使使用了线程池,libuv 的方法也不是线程安全的

2、API

2.1、uv_queue_work

int uv_queue_work(uv_loop_t* loop,
uv_work_t* req,
uv_work_cb work_cb,
uv_after_work_cb after_work_cb);

添加一个任务到工作队列中,在主线程中调用

loop: 事件循环

req: 传入到任务的数据,一般使用 req.data 参数传递

work_cb: 执行方法

after_work_cb: 执行方法完成后执行

work_cb 方法会在函数中执行,after_work_cb 方法在创建线程中执行

void (*uv_work_cb)(uv_work_t* req);
void (*uv_after_work_cb)(uv_work_t* req, int status);

如果调用 uv_cancel 方法取消了队列,则 uv_after_work_cbstatusUV_ECANCELED

2.2、uv_cancel

int uv_cancel(uv_req_t* req);

取消未执行的队列中的任务,在任务中调用

req 为任务的参数

如果调用此方法取消了任务,则 after_work_cb 回调函数的 status 的值为 UV_ECANCELED

3、代码示例

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <uv.h> void print(uv_work_t *req)
{
sleep(1);
long num = (long)req->data;
printf("thread id is: %ld, num is: %d\n", uv_thread_self(), num);
} void after_print(uv_work_t *req, int status)
{
printf("after print, req data is %d, status is %d\n", req->data, status);
} int main()
{
uv_loop_t *loop = uv_default_loop();
uv_work_t req[5]; for (int index = 0; index < 5; index++)
{
req[index].data = (void *)(long)index;
uv_queue_work(loop, &req[index], print, after_print);
sleep(1);
} return uv_run(loop, UV_RUN_DEFAULT);
}

示例中的代码,每次执行 print() 方法都是在不同线程中,after_print() 方法和 main() 方法在同一个线程中

libuv工作队列的更多相关文章

  1. 数据密集型 和 cpu密集型 event loop

    Node.js在官网上是这样定义的:“一个搭建在Chrome JavaScript运行时上的平台,用于构建高速.可伸缩的网络程序.Node.js采用的事件驱动.非阻塞I/O模型使它既轻量又高效,是构建 ...

  2. 转:Node.js软肋之CPU密集型任务

    文章来自于:http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks Node.js在官网上是这样定义的:“一个搭建在C ...

  3. TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)

    使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...

  4. libuv源码分析前言

    Libevent,libev,libuv三者的区别所在? libevent提供了全套解决方案(事件库,非阻塞IO库,http库,DNS客户端),然而libevent使用全局变量,导致非线程安全.它的w ...

  5. Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析

    声明:本文为原创博文,转载请注明出处.         在libuv中,请求(request)代表一个用户向libuv发出的指令,比如uv_connect_s就表示一个tcp的连接请求.uv_work ...

  6. Nodejs事件引擎libuv源码剖析之:句柄(handle)结构的设计剖析

    声明:本文为原创博文,转载请注明出处. 句柄(handle)代表一种对持有资源的索引,句柄的叫法在window上较多,在unix/linux等系统上大多称之为描述符,为了抽象不同平台的差异,libuv ...

  7. Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

    声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...

  8. Nodejs事件引擎libuv源码剖析之:高效队列(queue)的实现

     声明:本文为原创博文,转载请注明出处. 在libuv中,有一个只使用简单的宏封装成的高效队列(queue),现在我们就来看一下它是怎么实现的. 首先,看一下queue中最基本的几个宏: typede ...

  9. linux下libuv库安装教程

    下载并编译libuv libuv需要自己手动下载源码,并手动编译. 当前目录为:/home/xlz/test/github,在后面,会用$PATH来代替,我的系统的Debian8,64bit. $gi ...

随机推荐

  1. NET 5使用HangFire定时任务

    注意:1. 当Hangfire服务由Web程序来启用时,默认情况下,web应用程序中的Hangfire服务器实例在第一个用户访问您的站点之前不会启动.甚至,有一些事件会在一段时间后导致web应用程序关 ...

  2. Java与C#

    Java和C#都是编程的语言,它们是两个不同方向的两种语言 相同点: 他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装,继承,多态) 区别: 1.c#中的命名空间是namespace ...

  3. SpringCloud 源码系列(5)—— 负载均衡 Ribbon(下)

    SpringCloud 源码系列(4)-- 负载均衡 Ribbon(上) SpringCloud 源码系列(5)-- 负载均衡 Ribbon(下) 五.Ribbon 核心接口 前面已经了解到 Ribb ...

  4. python初学者-代码规范

    一.编程规范 1.缩进(代码块) 类定义.函数定义.选择结构.循环结构.with块.行尾的冒号表示缩进的开始. python程序是依靠代码块的缩进来体现代码之间的逻辑关系,缩进结束就表示一个代码块结束 ...

  5. Flowable—多实例任务:会签

    多实例任务 会签 什么是会签? 举个例子:比如我们有一个任务 可能需要多人审批,审批通过的条件可能比较多样,比如五个人审批.3个人审批过了就算过了,再或者有一个人权限比较高,拥有一票否决权. 即是其余 ...

  6. 推荐使用并手写实现redux-actions原理

    @ 目录 一.前言 二.介绍 2.1 创建action 2.2 reducer 2.3 触发action 三. 认识与手写createAction() 3.1 用法 3.2 原理实现 四.认识hand ...

  7. 一道java算法题

    12个人围成一圈,序号依次从1至12,从序号1开始顺时针依次数,数到7的人退出,下一个再依次从1开始数,求留下来的最后一个人的原始序号. public static void joseph(int[] ...

  8. mysql数据库连接java

    1 1.创建配置文件jdbc.properties 2 3 jdbc.driver=com.mysql.jdbc.Driver 4 jdbc.url=jdbc:mysql://localhost:33 ...

  9. springboot源码解析-管中窥豹系列之项目类型(二)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

  10. 【Nginx学习笔记】-初识Nginx

    Nginx 目录 Nginx Nginx 特点 Nginx 基本功能 Nginx 使用场景 Nginx 安装/卸载 Docker 方式运行 Ubuntu上安装 卸载Nginx Nginx 命令 Ngi ...