资讯专栏INFORMATION COLUMN

node - 非阻塞的异步 IO

oneasp / 755人阅读

摘要:而线程是进程的一部分,二者相扶相依,其中单线程被称为轻权进程或轻量级进程,执行特性线程只有个基本状态就绪,执行,阻塞。以上所述证明了操作与其他函数的这种区别是由实现,是用多线程的方式,在标准的阻塞式上模拟非阻塞异步,线程池默认限制四线程。

node - 非阻塞的异步 IO

每当我们提起 node.js 时总会脱口而出 事件驱动非阻塞I/O单线程,所以我总结了以下几点对这三项概念的阐述,不一定正确仅仅代表个人观点。

单线程

当一个应用程序运行时会产生一个主进程,它与其他并行执行的应用程序一起竟争计算机系统资源,是管理和分配现有所占据资源的基本单位。每一个进程都有一个自己的地址空间(进程空间)。而线程是进程的一部分,二者相扶相依,其中单线程被称为轻权进程或轻量级进程,执行特性:

线程只有 3 个基本状态:就绪,执行,阻塞。

线程存在 5 种基本操作来切换线程的状态:派生,阻塞,激活,调度,结束。

下面这个图片简单解释了单线程的运作:

用 php、apache、nginx 和 node.js 做对比是因为这四个应用恰好代表四种情况,其中 php 是典型的多线程的语言,apache 则是同步多进程的代表,也就是说连接每一个连接 apache 都对应一个子进程,而 nginx 是异步多线程,近万个连接对应一个子进程。

线程与非阻塞IO

当我们说 node.js 是单线程应用的时候,实际上这种单线程只是代码执行主程序上的单线程,在涉及到 IO 操作时仍然是多线程,下面我们看一段代码:

var path = require("path"),
    fs   = require("fs");

var i = 0;
console.time("fs.read");
fs.read(fs.openSync(path.join(__dirname, "example.log"), "r"), 10000, 0, "utf-8", function () {
    console.log("1");
    console.timeEnd("fs.read");
});
console.log("2");
function test(cb) {
    console.time("test");
    console.log("3");
    while (i < 300000000) {
        i++
    }
    cb()
}
console.log("4");
test(function () {
    console.log("5");
    console.timeEnd("test");
});
console.log("6");
//process.exit();

运行结果时:

数字标识分别为2、4、3、5、6、1,fstest 同样是回调函数一个立即执行并顺序执行,而另一个延迟执行,这显然不符合传统的程序执行顺序,也不符合有些人说的: 这种以定义当前感兴趣事件发生时由系统调用的函数来取代应用返回值的编程风格被称为事件驱动编程或者异步编程,这句话的错误在于是事件驱动编程 但不一定是异步编程异步编程 的先决条件是当前执行函数正在进行 IO 操作。

如果我们把上述代码的最后一句 //process.exit(); 的注释拿掉,可以看到执行结果:

这种情况是因为 fs 的 IO 操作是异步,并且执行结果在 事件驱动编程事件队列 的最低端,而在它之前 process.exit(); 已经在 事件循环 过程中被从事件队列中取出放入调用堆栈,结束了主进程。所以发生 fs 的回调结果没有显示,因为它已经被放在了整段代码执行环境中的 事件队列 的最下方(这里就是非阻塞的实例)。

以上所述证明了 IO 操作与其他函数的这种区别是由 libeio 实现,libeio 是用多线程的方式,在标准的阻塞式IO上模拟非阻塞异步,线程池默认限制四线程。

另外的 libev 事件可得到 IO 执行状态。Node.js 的开发者在 libev 和 libeio 的基础上还抽象出了 libuv 层: (http://docs.libuv.org/en/v1.x/design.html)。
所有的 IO操作都会转发给由 libuv 管理的工作线程去执行,由 libuv 与 libev 和 libeio 进行交互。

事件驱动

事件驱动与事件循环互为犄角,其中事件循环具备两个功能:

事件检测

事件触发处理

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/49934.html

相关文章

  • node.js异步IO 第一篇

    摘要:给出了解决方案就是单线程,远离线程锁,状态同步的问题,使用异步让单线程远离阻塞,高效利用。而实际上的异步是采用了线程池技术,发起异步时,把操作扔到线程池里面执行,然后主线程继续执行其他操作,执行完毕通过线程间通信通知主线程,主线程执行回调。 异步IO,事件驱动,单线程构成了node的基调,为什么异步IO在node中如此重要呢? 我们先来说一下异步的概念,异步常见于前端开发,例如ajax...

    feng409 评论0 收藏0
  • node - 阻塞异步 IO

    摘要:而线程是进程的一部分,二者相扶相依,其中单线程被称为轻权进程或轻量级进程,执行特性线程只有个基本状态就绪,执行,阻塞。以上所述证明了操作与其他函数的这种区别是由实现,是用多线程的方式,在标准的阻塞式上模拟非阻塞异步,线程池默认限制四线程。 node - 非阻塞的异步 IO 每当我们提起 node.js 时总会脱口而出 事件驱动、非阻塞I/O 和 单线程,所以我总结了以下几点对这三项概念...

    yuxue 评论0 收藏0
  • node - 阻塞异步 IO

    摘要:而线程是进程的一部分,二者相扶相依,其中单线程被称为轻权进程或轻量级进程,执行特性线程只有个基本状态就绪,执行,阻塞。以上所述证明了操作与其他函数的这种区别是由实现,是用多线程的方式,在标准的阻塞式上模拟非阻塞异步,线程池默认限制四线程。 node - 非阻塞的异步 IO 每当我们提起 node.js 时总会脱口而出 事件驱动、非阻塞I/O 和 单线程,所以我总结了以下几点对这三项概念...

    keelii 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<