libuv 使用,libudev
Node.js Node.js是一个基于Chrome V8引擎的JavaScript运行时环境。Node.js使用事件驱动的非阻塞I/O模型,使其轻量级且高效。Node.js包管理器npm是世界上最大的开源库生态系统。Ryan Dahl正在编写一些开源项目,帮助客户解决Web服务器的高并发性能问题。试过的语言有Ruby,C和Lua。虽然这些尝试最后都失败了,但是只有用C写的HTTP服务库libebb略有改进,基本上是libuv的前身。这些失败都有自己的原因。Ruby因为虚拟机性能差,解决不了根本问题。c代码有很高的性能,但是让业务通过c开发和展示是不现实的,Lua现有的同步I/O无法充分发挥其性能优势。尽管失败了,但Ryan Dahl普遍觉得解决问题的关键是通过事件驱动和异步I/O来达到目的,在他绝望的时候,V8引擎来了,V8满足了他关于高性能Web服务器的现象:
没有历史包袱,没有同步I/O,不会出现一个同步I/O导致事件周期性能急剧下降的情况。V8性能足够好,远远快于Python、Ruby等其他脚本语言的引擎。JavaScript的闭包特性非常方便,而且比c中的回调函数要好,于是在2009年2月,按照新的思路,他提交了项目的第一行代码,项目名最终定义为node。
Node.js是专注于高性能Web服务器优化的专家。几经摸索和挫折,诞生了V8。
libuv Node.js底层库是用c语言编写的libuv库,为了解决跨平台异步I/O读写。Libuv是一个高性能的事件驱动的大型异步IO库,用C语言编写,具有很高的可移植性。Libuv封装了异步IO模型在不同平台的实现,具有Windows和Linux都可以使用的跨平台能力。Libuv是一个跨平台的库,专注于异步IO,著名的事件循环是libuv的一大特色。Libuv是后来专门为Node.js设计的,由于事件驱动异步IO的高效性,逐渐被其他语言和项目采用,多被自己的底层库使用。Node.js刚出来的时候,底层不是libuv而是libev。libev本身是一个异步IO库,但是只能在POSIX系统下使用。随着越来越多的人使用Node.js和数量庞大的Windows用户,我们开始考虑Node.js的跨平台能力。
此时Node.js提供libnv作为抽象封装层,通过在UNIX系统上封装libev和libio来调用Linux的epoll或kqueue,在Windows上封装在IOCP上。从此,Node.js具备了跨平台能力。Libuv是中间层自己提供的跨平台抽象,以便根据系统决策使libev/libio或IOCP更实用。在Node.js v0.9.0版本中,libuv删除了libev的内容。
node.js libuv的特性使用C语言实现的异步事件网络库libevent、libev和libuv。
LibeEvent是一个历史悠久、应用最广泛的跨平台事件库,它的设计比LibeEvent更简单,性能也更好,但对Windows的支持不够友好。Libuv在开发node的过程中需要一个跨平台的事件库。起初首选libev但需要支持windows,然后在linux下封装libev,在windows下封装IOCP,形成libuv库。Libuv采用异步和事件驱动的编程风格,主要任务是为开发者提供一套基于I/O通知的事件循环和回调函数。
Libuv提供了一套核心工具,如定时器、支持无阻塞网络编程、异步访问文件系统、子进程等功能。
Libuv支持的功能
Linux下基于epoll的操作系统支持的事件循环机制、Windows下基于IOCP的MAC OS、UNIX下基于kqueue、FreeBSD下基于evports的异步TCP/UDP通信、异步文件读写的异步DNS解析、基于ANSII控制字符的文件系统事件机制TTYIPC、流水线通信多进程、线程信号量处理、高分辨率、始终多线程、同步运行。异步程序最基本的活动是处理输入和输出,而不是大量的数值计算。read、fprintf等传统输入输出函数的问题被阻塞,这意味着将数据写入磁盘或从网络读取数据将需要大量的时间。阻塞函数直到任务完成才会返回,在此期间程序什么都做不了,浪费了大量的CPU时间。对于追求高性能的程序,当其他活动或I/O操作正在进行时,应该避免CPU被阻塞。标准的解决方案是使用线程,每个阻塞的IO操作都在一个单独的线程或线程池中启动。但是当阻塞函数被调用时,处理器可以调度另一个真正需要CPU来执行任务的线程。
Libuv使用另一种方式来处理阻塞任务,即异步和非阻塞方式。现代操作系统都提供事件通知功能。例如,调用read读取网络套接字会阻塞,直到发送方最终发送数据,read才会返回。但是,应用程序可以要求操作系统监视套接字并在套接字上注册事件通知。应用程序可以查看它所监控的事件,并在适当的时候获取数据。整个过程是异步的,因为程序在一个时刻关注自己感兴趣的事件,在另一个时刻获取或使用数据。这也是不堵的。因为这个过程也可以处理其他任务。
libuv的事件循环模式很好的匹配了模型,因为操作系统事件可以看作是另一个libuv事件,非阻塞模式可以保证其他事件来了也会尽快处理。
事件循环(Event Loop)在事件编程模型中,应用程序通常会关注一个特定的事件,并在事件发生后对其做出响应,而收集事件或监控其他事件源则是libuv的职责。程序员只需要为感兴趣的事件注册回调函数,libuv会在事件发生后调用相应的回调函数。主程序不退出,事件循环通常一直运行。
适合事件驱动编程模型的场景
文件已准备好写入数据。套接字上有数据。可读计时器已超时。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。