이 글에서는 주로 참고할만한 가치가 있는 노드 비동기 I/O에 대해 소개합니다. 도움이 필요한 친구들이 참고할 수 있도록 하겠습니다.
Javascript는 UI 스레드와 동일한 스레드인 단일 스레드에서 실행됩니다. 동기화를 사용하는 경우 JavaScript가 실행될 때 UI 렌더링이 대기를 중지해야 하므로 사용자 경험이 매우 저하됩니다.
웹 페이지가 일부 리소스를 요청하고 이를 동기식으로 가져와야 하는 경우 실행을 계속하기 전에 js가 서버에서 리소스를 완전히 가져올 때까지 기다려야 합니다. 이 기간 동안 UI는 대기하며 이는 사용자가 매우 열악하고 사용자 경험에 영향을 미칩니다.
// 现在请求两个资源 //耗时为M毫秒 getData('from_db'); //耗时为N毫秒 getData('from_remote_api');
동기식이면 (M + N)
시간이 걸립니다.
Max(M, N)
시간이 걸립니다. (M + N)
;
如果是异步,需要耗时Max(M, N)
;
随着应用的复杂性,情景会变成M+N+...和Max(M,N,...)
,此时同步和异步的优劣就会更加凸显。另一方面,随着网站和应用的扩展,数据往往会分布到多台服务器上,而分布意味着M和N的值会线性增长,这也会放大异步和同步在性能上的差异。总之,IO是昂贵的,分布式IO是更昂贵的!
资源分配
单线程同步IO
会因阻塞IO使得硬件资源无法得到更优的利用。
多线程编程
优点: 可以利用多核CPU有效提升CPU的利用率 缺点: 编程中的死锁、状态同步使得程序员很是头疼。
node的异步IO
node采用的异步IO,利用单线程,远离了多线程死锁、状态同步,利用异步让单线程远离了阻塞,使得CPU得到更好的利用。 为了弥补单线程无法利用多核CPU的问题,Node提供了子进程 `childProcess` ,将一些运算多的任务放入子进程进行高效的运算。
二、阻塞I/O 和 非阻塞 I/O
阻塞IO
阻塞的IO操作就是发起IO操作后,线程阻塞等待IO完成,这期间cpu得不到有效利用。
非阻塞IO
非阻塞IO操作其实就是发起IO操作后,通过事件轮巡,或者事件通知机制,不断查询IO操作是否完成,或者是主线程进入休眠等待事件通知IO结束,然后继续向下执行代码,实际上非阻塞IO期间,cpu要不用来查询要不用来休眠,也没有得到有效利用。依旧是同步IO。
完成整个异步IO需要单个环节 事件循环
观察者
请求对象
。
实际上node的异步IO是采用了线程池技术,发起异步IO时,把io操作扔到线程池里面执行,然后主线程继续执行其他操作,io执行完毕通过线程间通信通知主线程,主线程执行回调。
IO线程是由Libuv
(Linux
下由libeio
具体实现;window
下则由IOCP
具体实现)管理的线程池控制的,本质上是多线程。即采用了线程池
与阻塞IO
模拟了异步IO
애플리케이션이 복잡해지면 시나리오는 M+N+... 및 Max(M, N,...)
가 됩니다. 이때 동기식과 비동기식의 장단점은 다음과 같습니다. 더욱 두드러지게 됩니다. 반면, 웹사이트와 애플리케이션이 확장되면서 데이터가 여러 서버에 분산되는 경우가 많으며, 분산된다는 것은 M과 N의 값이 선형적으로 증가한다는 것을 의미하며, 이는 비동기식과 동기식의 성능 차이도 증폭시키게 됩니다. 즉, IO는 비용이 많이 들고, 분산 IO는 훨씬 더 비쌉니다!
리소스 할당
단일 스레드 동기 IOrrreee
멀티 스레드 프로그래밍
rrreee
노드의 비동기 IO
🎜🎜🎜비차단 IO🎜🎜rrreee🎜🎜🎜3. 노드의 비동기 I/O🎜🎜전체 비동기 IO를 완료하려면 단일 링크이벤트 루프 <code>관찰
요청 개체
. 🎜🎜실제로 노드의 비동기 IO는 스레드 풀 기술을 사용합니다. 비동기 IO가 시작되면 io 작업이 실행을 위해 스레드 풀에 던져지고, io 실행이 완료된 후 메인 스레드가 계속해서 다른 작업을 수행합니다. 스레드 간 통신을 통해 메인 스레드에 알림이 전달됩니다. 🎜🎜IO 스레드는 Libuv
(libeio
의 Linux
, 의 <code>window
아래)에 의해 구체적으로 구현됩니다. IOCP(특정 구현)에 의해 관리되는 스레드 풀에 의해 제어되며 본질적으로 다중 스레드입니다. 즉, 스레드 풀
과 블로킹 IO
는 비동기 IO
를 시뮬레이션하는 데 사용됩니다. 🎜🎜🎜🎜🎜🎜비동기 IO의 원리🎜🎜🎜IO가 발생하면 이를 스레드 풀의 IO 스레드에 넣고 IO 스레드에서 작업을 실행하도록 IO 스레드를 차단합니다. 그런 다음 메인 스레드에서 실행을 계속합니다. 다른 IO 작업이 발생하면 이를 스레드 풀에 넣은 다음 다른 IO 스레드(또한 차단 IO 모드)에서 실행하면 메인 스레드가 계속 실행됩니다. 🎜🎜위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되었으면 좋겠습니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요! 🎜🎜관련 권장사항: 🎜🎜🎜Node 모듈 메커니즘 분석에 대하여🎜🎜🎜🎜🎜Node 기본 개념 소개🎜🎜🎜위 내용은 노드 비동기 I/O 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!