libuv工作队列
1、说明
libuv 提供了一个线程池,可用于运行用户代码,libuv 中的工作队列中的任务会在线程池中执行
libuv 中的线程池在内部用于运行所有文件系统操作以及 getaddrinfo() 和 getnameinfo() 请求
libuv 中的线程池的默认数量为4,可以在启动时修改环境变量 UV_THREADPOOL_SIZE 来修改,最大值为 1024(1.30.0版本之前是128)
libuv 中的线程池是全局的,并在所有事件循环之间共享,当特定的函数利用 uv_queue_work() 方法使用工作队列时,libuv 会预分配线程池,以较小的内存开销(128个线程为1MB),来提高线程性能
以下三种类型的操作会在全局线程池中进行:
- 文件系统操作;
- DNS函数(getaddrinfo 和 getnameinfo);
- 使用 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_cb 的 status 为 UV_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工作队列的更多相关文章
- 数据密集型 和 cpu密集型 event loop
Node.js在官网上是这样定义的:“一个搭建在Chrome JavaScript运行时上的平台,用于构建高速.可伸缩的网络程序.Node.js采用的事件驱动.非阻塞I/O模型使它既轻量又高效,是构建 ...
- 转:Node.js软肋之CPU密集型任务
文章来自于:http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks Node.js在官网上是这样定义的:“一个搭建在C ...
- TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)
使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...
- libuv源码分析前言
Libevent,libev,libuv三者的区别所在? libevent提供了全套解决方案(事件库,非阻塞IO库,http库,DNS客户端),然而libevent使用全局变量,导致非线程安全.它的w ...
- Nodejs事件引擎libuv源码剖析之:请求(request)结构的设计剖析
声明:本文为原创博文,转载请注明出处. 在libuv中,请求(request)代表一个用户向libuv发出的指令,比如uv_connect_s就表示一个tcp的连接请求.uv_work ...
- Nodejs事件引擎libuv源码剖析之:句柄(handle)结构的设计剖析
声明:本文为原创博文,转载请注明出处. 句柄(handle)代表一种对持有资源的索引,句柄的叫法在window上较多,在unix/linux等系统上大多称之为描述符,为了抽象不同平台的差异,libuv ...
- Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现
声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程 ...
- Nodejs事件引擎libuv源码剖析之:高效队列(queue)的实现
声明:本文为原创博文,转载请注明出处. 在libuv中,有一个只使用简单的宏封装成的高效队列(queue),现在我们就来看一下它是怎么实现的. 首先,看一下queue中最基本的几个宏: typede ...
- linux下libuv库安装教程
下载并编译libuv libuv需要自己手动下载源码,并手动编译. 当前目录为:/home/xlz/test/github,在后面,会用$PATH来代替,我的系统的Debian8,64bit. $gi ...
随机推荐
- C# AutoMapper:流行的对象映射框架,可减少大量硬编码,很小巧灵活,性能表现也可接受。
AutoMapper 是一个对象-对象映射器,可以将一个对象映射到另一个对象. 官网地址:http://automapper.org/ 官方文档:https://docs.automapper.org ...
- EF快速入门--直接修改(简要介绍ObjectContext处理机制)
原博文 http://www.cnblogs.com/fly_dragon/archive/2011/06/05/2073084.html ObjectContext的处理机制 ObjectConte ...
- 4.mysql profile的使用方法
profile的使用 1.作用 使用profile可以对某一条sql性能进行分析 2.语法 mysql> show variables like '%profil%'; +----------- ...
- 将两个ListMap中同下标的map去重合并
public static void main(String[] args) { Map<String,Object> oneMap = new HashMap<>(); on ...
- bean中属性名和json不一致解决方案(请求和响应)
此时@RequestBody.@ResponseBody需要与@JsonProperty结合使用,才能做到请求正常解析,响应按要求格式返回. 注意@JsonProperty注解的位置需要加在gette ...
- git fork , git pull request那回事
git fork 原理 相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request,这样原项目的作者就可以将你修改的东西合并到 ...
- 关于vuex的数据不直接给data而要通过computed
# 为什么vuex的数据不直接给data而要通过computed计算 ## 疑惑 其实一直以来使用vue的状态管理vuex都有一个疑惑,文档中介绍,vue的状态数据`$store.state.xx`的 ...
- 【JDBC核心】实现 CRUD 操作
实现 CRUD 操作 操作和访问数据库 数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果.其实一个数据库连接就是一个 Socket 连接. java.sql 包中有 ...
- 【剑指 Offer】09.用两个栈实现队列
题目描述 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead , 分别完成在队列尾部插入整数和在队列头部删除整数的功能.(若队列中没有元素,del ...
- 在Windows中安装MongoDB--图文并茂
在Windows环境下安装MongoDB的方法 (1)下载MongoDB Windows版: 进入MongoDB官网 (2)设置数据文件和日志文件的存放目录: 打开刚刚安装MongoDB的目录咋bin ...