转载自:http://snoopyxdy.blog.163.com/blog/static/601174402013422103614385/
最近cnode上很多TX在问关于node的异步回调以及单线程的事情,今天看了libuv的一些api和demo,自己简单写了一个利用libuv实现异步多线程的addon的例子,真心希望大牛指正啊。
首先介绍下libuv,libuv 是一个高性能事件驱动的程序库,封装了 Windows 和 Unix 平台一些底层特性,为开发者提供了统一的 API。libuv 采用了 异步 (asynchronous), 事件驱动 (event-driven)的编程风格, 其主要任务是为开人员提供了一套事件循环和基于I/O(或其他活动)通知的回调函数, libuv 提供了一套核心的工具集, 例如定时器, 非阻塞网络编程的支持, 异步访问文件系统, 子进程以及其他功能。
可见nodejs的一切异步操作都是基于libuv来实现的,有了它的这些api我们也就可以编写出异步的nodejs模块了。
最好结合github上的test和liuv.h来看,更加容易弄懂
中文版的libuv手册:http://forhappy.github.io/uvbook/index.html
libuv项目地址:https://github.com/joyent/libuv
简单介绍一下这个demo实例把,我在demo里写了5个例子,分别用了不同的技术,执行了10次fibo(40),最后所得到的结果也各不相同。
c++代码都在 ./src 文件夹中,Asyn类中定义了下述5种不同情况的方法和一些libuv的api所需要的回调函数,在job类中,定义了执行fibo的任务函数,和一些相关设置,在线程中或者异步回调中传递的都是job类的指针。
例子执行代码如下:
//do fibo 10 times
var i = 40;
var times = 10;
asyn.sync(times,i,function(err, result){//1、这里执行10次fibo(40)的函数,分别用不同的技术
console.log('fibo('+i+'):' + result)
})
var d1 =Date.now();
while(Date.now()- d1 <=1000*1){//2、这里将主线程sleep 1秒,模拟js的执行工作
//sleeping 10sec simulate the js work
}
我们分别以5种不同的方式执行10次fibo(40),看看测试结果会是什么样子的,我们主要记录全部执行任务的时间和模拟的js任务执行的时间。
1、完全同步,在c++代码中直接10次循环执行fibo(40)
执行测试代码:
main_thread_js_work:4568ms
sync_all_the_work:4568ms
2、使用libuv创建同步线程来计算fibo,然后将结果回调主线程
执行测试代码:
main_thread_js_work:4595ms
sync_thread_all_the_work:4595ms
3、使用libuv的async异步回调方式,将所有任务注册到事件循环中,这样将先执行js的sleep,然后在主线程中分别计算fibo的结果,这种情况有点像我们使用process.nextTick来让一个计算异步执行,保证当前主线程的工作不被阻塞,最后进行耗时计算。
执行测试代码:
main_thread_js_work:1003ms
asyn_all_the_work:4457ms
因为我们将fibo放在了异步去执行,所以js的任务将被先执行,js任务执行了1秒(我们模拟sleep了1秒)之后就是fibo的任务,总时间和上面两种情况大致相同。4、使用libuv的async异步回调的方式,我们先注册fibo执行完毕的异步回调函数,然后创建异步的线程去执行fibo,这样js的任务将和fibo线程同时进行工作.
main_thread_js_work:1017ms
asyn_thread_all_the_work:1897ms
因为js任务抢占着主线程,同时也是因为js任务执行时间比较短,所以js任务结束提示先打印到了屏幕上,然后各异步线程也执行完毕,总耗时1897ms,比上面几种情况要快一倍,这主要归功于多核CPU的同时计算5、使用libuv自带的线程池进行异步计算fibo,我们先向线程池注册工作回调,然后再注册主线程的完成回调
main_thread_js_work:1002ms
asyn_pool_all_the_work:2382ms
这种情况和上述情况一样,不过我们不是为每个计算生成一个线程,而是使用了libuv内部的线程池,所以制约了并行计算的能力,但是这样更加安全,不容易因为不可控的线程数量导致程序崩溃,事实上libuv为我们提供了4个线程的线程池。
总结一下,使用libuv我们最好采用可控的异步线程配合异步回调来做一些事情,这样可以不阻塞主的js线程,还能并行执行任务,当任务结束后记得一定要回调主线程去执行js的回调函数,不能在其他线程去执行js的回调,因为在v8的一个isolate中,不可以多个线程同时操作一个isolate。当我们在线程中操作共享变量时记得加锁和解锁。在异步任务执行完毕后记得执行uv_close,将其关闭,同时因为我们都是将指针作为参数传递的,不要忘记delete掉之前new的指针,这样通过libuv的异步多线程api,我们就可以很轻松的为nodejs编写一些跨平台非阻塞扩展了。
PS,经过在win8 64位 和 linux 2.6.4 32bit虚拟机的测试中,我发现win8真是弱爆了,linux虚拟机执行上述任务的所消耗时间比我真机win8还要少一些。
相关推荐
本文将深入探讨“模拟摄像头libuv支持多线程并发”这一主题,结合“模拟IPC”这一标签,以及文件名称“IpcSimulate”,我们将分析如何利用libuv库在多线程环境下实现模拟摄像头的功能。 首先,让我们了解一下什么是...
服务端代码进行封装,libuv以及pjsip等,支持扩展,便于开发.
libuv是一个专注于高性能、事件驱动I/O的跨平台库,其主要特色在于为开发者提供了一套统一的事件循环机制,无论是在Windows还是Unix...通过理解libuv的核心概念和API,开发者能够编写出跨平台、性能优异的异步程序。
- **单线程与多线程**:libuv允许开发者在一个单独的线程中处理所有事件,同时也可以利用多线程来扩展处理能力,根据应用需求选择合适的策略。 2. **libuv的主要组件** - **事件循环(Event Loop)**:libuv的...
通过阅读这些文档,开发者可以学习到如何利用libuv进行并发编程,实现高效的异步操作。libuv的事件驱动模型能够提高程序的性能,减少资源消耗,尤其是在处理大量并发请求时。理解libuv的工作原理对于提升Node.js或...
libuv是一个用C语言编写的库,它的主要目标是提供一个统一的接口来处理跨平台的异步I/O操作。它包括对TCP、UDP、管道、文件系统事件、信号、子进程等的支持。在Node.js中,libuv被用来处理所有非JavaScript运行时的...
libuv是一款由node.js核心团队开发的高性能、事件驱动的I/O库,它为开发者提供了一套跨平台的API,包括对文件系统、网络、进程、线程以及异步I/O操作的支持。libuv的API调用方式类似于Linux下的pthread,适用于需要...
- **线程和进程管理**: 支持线程池、子进程创建与通信,便于进行多线程和分布式计算。 - **信号处理**: 可以注册信号处理器,接收并处理来自操作系统的信号,如SIGINT、SIGTERM等。 - **内存管理和日志记录**: ...
- **构建网络服务器**:利用libuv的异步TCP和UDP支持,可以轻松构建高并发的网络服务器。 - **文件操作**:libuv的异步文件系统接口允许在不阻塞主线程的情况下进行文件读写和目录遍历。 - **进程间通信**:通过...
本项目着重探讨了如何利用libuv库在C++环境中实现TCP客户端和服务器的通信。libuv是一个跨平台的异步I/O库,广泛应用于Node.js等项目,为开发者提供了高效且易于使用的网络编程接口。 1. libuv库介绍: libuv是一个...
总的来说,这个压缩包提供了一整套用于在项目中使用libuv的必要组件,使得开发者可以轻松地利用libuv的强大功能来构建高性能的异步应用。无论你是Node.js开发者还是纯C/C++程序员,libuv都能为你的项目带来卓越的...
深入学习 libuv-1.x 源码,不仅可以理解其背后的异步机制和设计原理,还能帮助开发者更好地利用 libuv 构建高性能、跨平台的应用程序。通过阅读源码,我们可以学习到如何有效地处理 I/O 操作、如何设计可扩展的事件...
它适用于任何需要进行高效异步操作的场景,如实时Web服务、数据库连接、多线程任务调度等。 6. **学习与实践libuv** 要深入理解libuv,需要熟悉事件驱动编程模式,了解基本的网络协议和操作系统I/O模型。实践上,...
线程间通信是多线程编程的一个重要方面,libuv提供了必要的工具和接口。 ### 6. 进程 #### 6.1 孵化子进程 libuv能够创建子进程,并管理它们的生命周期。 #### 6.2 更改进程参数 开发者可以在子进程启动前更改...
3. **异步 DNS 解析**:Libuv 可以在后台线程中执行 DNS 查询,避免了主线程的阻塞。 4. **信号处理**:它可以捕获和处理操作系统发送的信号,例如 SIGINT 和 SIGTERM,帮助程序优雅地处理退出。 5. **进程和线程...
libuv是一个基于C语言编写的高性能、事件驱动的I/O库,它提供了跨平台的API,支持如Windows、Linux等操作系统。libuv在设计上强调了事件驱动编程范式,其核心是提供一个event-loop(事件循环),以及基于I/O和其他...
虽然libuv主要依赖于单线程事件循环,但它允许开发者在需要时利用多线程进行计算密集型任务,提高程序性能。1.39.0版本的线程池优化了任务调度和资源管理,使得多线程协作更为顺畅。 总的来说,libuv-1.39.0是一个...
libuv是一个跨平台的异步I/O库,最初由Node.js项目开发并维护,现在已成为一个独立的开源库,广泛应用于需要高性能网络编程的场景。1.22.0是libuv在2018年7月发布的版本,它提供了对多种操作系统(如Windows、Linux...
- **Node.js模块开发**:对于`node.js`模块的开发者来说,`libuv`提供了一种方法,可以将用C/C++编写的平台API封装成异步API,以便在`node.js`环境中使用。 - **注意**:虽然`libuv`是`node.js`的一部分,但其用途...
6. **线程安全**:libuv 在多线程环境中的使用需要额外的同步措施,封装库会处理这些细节,确保在多线程环境下的正确运行。 7. **Windows 和 Linux 兼容**:libuv 已经跨平台,封装库同样如此,能够在 Windows 和 ...