草庐IT

Event Loop

方豆儿 2023-10-16 原文

Event Loop 是一个很重要的概念,指的是计算机系统的一种运行机制
JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题

1.png

想要理解Event Loop,就要从程序的运行模式讲起。运行以后的程序叫做"进程"(process),一般情况下,一个进程一次只能执行一个任务。

如果有很多任务需要执行,不外乎三种解决方法。

  • 排队。因为一个进程一次只能执行一个任务,只好等前面的任务执行完了,再执行后面的任务。
  • 新建进程。使用fork命令,为每个任务新建一个进程。
  • 新建线程。因为进程太耗费资源,所以如今的程序往往允许一个进程包含多个线程,由线程去完成任务。

以JavaScript语言为例,它是一种单线程语言,所有任务都在一个线程上完成,即采用上面的第一种方法。一旦遇到大量任务或者遇到一个耗时的任务,网页就会出现"假死",因为JavaScript停不下来,也就无法响应用户的行为。

你也许会问,JavaScript为什么是单线程,难道不能实现为多线程吗?

这跟历史有关系。JavaScript从诞生起就是单线程。原因大概是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。后来就约定俗成,JavaScript为一种单线程语言。(Worker API可以实现多线程,但是JavaScript本身始终是单线程的。)

如果某个任务很耗时,比如涉及很多I/O(输入/输出)操作,那么线程的运行大概是下面的样子。


2.png

上图的绿色部分是程序的运行时间,红色部分是等待时间。可以看到,由于I/O操作很慢,所以这个线程的大部分运行时间都在空等I/O操作的返回结果。这种运行方式称为"同步模式"(synchronous I/O)或"堵塞模式"(blocking I/O)。

如果采用多线程,同时运行多个任务,那很可能就是下面这样。


3.png

上图表明,多线程不仅占用多倍的系统资源,也闲置多倍的资源,这显然不合理。

Event Loop就是为了解决这个问题而提出的。[Wikipedia]这样定义:

  • "Event Loop是一个程序结构,用于等待和发送消息和事件。(a programming construct that waits for and dispatches events or messages in a program.)"

简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为"主线程";另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为"消息线程")。


4.png

上图主线程的绿色部分,还是表示运行时间,而橙色部分表示空闲时间。每当遇到I/O的时候,主线程就让Event Loop线程去通知相应的I/O程序,然后接着往后运行,所以不存在红色的等待时间。等到I/O程序完成操作,Event Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。

可以看到,由于多出了橙色的空闲时间,所以主线程得以运行更多的任务,这就提高了效率。这种运行方式称为"异步模式"(asynchronous I/O)或"非堵塞模式"(non-blocking mode)。

这正是JavaScript语言的运行方式。单线程模型虽然对JavaScript构成了很大的限制,但也因此使它具备了其他语言不具备的优势。如果部署得好,JavaScript程序是不会出现堵塞的,这就是为什么node.js平台可以用很少的资源,应付大流量访问的原因。

https://www.cnblogs.com/hanzhecheng/p/9046144.html JS中EventLoop事件循环机制

Event Loop 是什么
JavaScript的事件分两种,宏任务(macro-task)和微任务(micro-task)

  • 宏任务:包括整体代码script,setTimeout,setInterval
  • 微任务:Promise.then(非new Promise),process.nextTick(node中)
  • 事件的执行顺序,是先执行宏任务,然后执行微任务,这个是基础,任务可以有同步任务和异步任务,同步的进入主线程,异步的进入Event Table并注册函数,异步事件完成后,会将回调函数放入Event Queue中(宏任务和微任务是不同的Event Queue),同步任务执行完成后,会从Event Queue中读取事件放入主线程执行,回调函数中可能还会包含不同的任务,因此会循环执行上述操作。

https://www.cnblogs.com/mcray/p/6938417.html

有关Event Loop的更多相关文章

  1. node.js - Nodejs EventLoop(带集群模块)和Golang Scheduler的比较 - 2

    在nodejs中,主要批评者基于其单线程事件循环模型。nodejs最大的缺点是无法在应用程序中执行CPU密集型任务。为了演示目的,让我们以while循环为例(这可能类似于一个返回十万条记录的db函数,然后在nodejs中处理这些记录。)while(1){x++}此类代码将阻塞主堆栈,因此事件队列中等待的所有其他任务将永远没有机会执行。(而在web应用程序中,新用户将无法连接到该应用程序)。但是,可以使用像cluster这样的模块来利用多核系统并部分解决上述问题。Cluster模块允许创建一个由独立进程组成的小型网络,这些进程可以共享服务器端口,这使Node.js应用程序可以访问服务器的

  2. linux - MIO EventLoop 未针对 TcpStream 运行 - 2

    我是一名Rust初学者,正在为异步IO问题而苦苦挣扎。我决定使用mio.我已经阅读了一些源代码和教程,但仍有一些基本部分我不明白。我正在使用netcat-k-l127.0.0.19999设置服务器。然后我用cargo(下面的代码)运行简单的测试。我期待看到“准备好”或“滴答声”的panic。但它永远不会发生,测试会永远运行。externcratemio;usemio::*;#[allow(unused_imports)]usemio::tcp::TcpStream;#[allow(dead_code)]structMyHandler;implHandlerforMyHandler{ty

  3. 搞懂EventLoop机制 - 2

    写在最前:本文转自掘金#JavaScript是单线程的语言事件循环EventLoop,这是目前浏览器和NodeJS处理JavaScript代码的一种机制,而这种机制存在的背后,正是因为JavaScript是单线程语言。单线程和多线程最简单的区别就是:单线程同一个事件只能做一件事情,而多线程同一个时间能做多件事情。调用栈CallStack在JavaScript运行的时候,主线程会形成一个栈,这个栈主要是解释器用来最终函数执行流程的一种机制。通常这个栈被称为调用栈CallStack或者执行栈。调用栈,顾名思义是具有LIFO(后进先出,LastinFirstOut)的结构。调用栈内存放的是代码执行期

  4. EventLoop - 2

    ?EventLoopJS是单线程的,也就是,同一时间只能做一件事情。所以一旦遇到大量任务或者耗时的任务时,比如加载高清图片,网页就会“假死”,无法响应用户的行为。为了防止这种阻塞,才有了同步和异步的概念。而EventLoop,即事件循环机制,就是我们经常使用异步的原理。同步任务非耗时的任务,指的是在主线程上排队执行的那些任务只有前一个任务执行完毕,才能执行后一个任务console.log('111')console.log('222')console.log('333')上述就是简单的同步任务,会按照顺序输出111,222,333异步任务耗时任务,异步任务由JS委托给宿主环境进行执行当异步任务

  5. EventLoop - 2

    ?EventLoopJS是单线程的,也就是,同一时间只能做一件事情。所以一旦遇到大量任务或者耗时的任务时,比如加载高清图片,网页就会“假死”,无法响应用户的行为。为了防止这种阻塞,才有了同步和异步的概念。而EventLoop,即事件循环机制,就是我们经常使用异步的原理。同步任务非耗时的任务,指的是在主线程上排队执行的那些任务只有前一个任务执行完毕,才能执行后一个任务console.log('111')console.log('222')console.log('333')上述就是简单的同步任务,会按照顺序输出111,222,333异步任务耗时任务,异步任务由JS委托给宿主环境进行执行当异步任务

  6. js EventLoop、宏任务和微任务 - 2

    1.javascript是单线程的语言javascript是一门单线程执行的编程语言。也就是说,同一时间只能做一件事情。如下:如果有多个任务要执行,执行其他任务时,其他任务都要进行等待52.png1.1单线程执行任务队列的问题如果前一个任务非常耗时,则后续的任务不得不一直等待,从而导致程序假死的问题。2.同步任务和异步任务为了防止某个耗时任务导致程序假死的问题,javascript把待执行的任务分为了两类。同步任务又叫做非耗时任务,指的是在主线程上排队执行的那些任务只有前一个任务执行完毕,才能执行后一个任务异步任务又叫做非耗时任务,异步任务由javascript委托给宿主环境进行执行当异步任务

  7. js EventLoop、宏任务和微任务 - 2

    1.javascript是单线程的语言javascript是一门单线程执行的编程语言。也就是说,同一时间只能做一件事情。如下:如果有多个任务要执行,执行其他任务时,其他任务都要进行等待52.png1.1单线程执行任务队列的问题如果前一个任务非常耗时,则后续的任务不得不一直等待,从而导致程序假死的问题。2.同步任务和异步任务为了防止某个耗时任务导致程序假死的问题,javascript把待执行的任务分为了两类。同步任务又叫做非耗时任务,指的是在主线程上排队执行的那些任务只有前一个任务执行完毕,才能执行后一个任务异步任务又叫做非耗时任务,异步任务由javascript委托给宿主环境进行执行当异步任务

随机推荐