この記事では主に Node 非同期 I/O の紹介を紹介します。これは、必要な友達に参考にしてもらいたいです
JavaScript は UI スレッドと同じ単一スレッドで実行されます。同期を使用する場合、JavaScript の実行時に UI レンダリングの待機を停止する必要があり、その結果、ユーザー エクスペリエンスが非常に低下します。
Web ページがいくつかのリソースをリクエストして同期的に取得する必要がある場合、実行を続ける前に、js がサーバーからリソースを完全に取得するまで待つ必要があります。この間、UI は待機し、これにより 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,...)
になります。このとき、同期と非同期のメリットとデメリットが異なります。より目立つようになります。一方で、Web サイトやアプリケーションが拡大するにつれて、データが複数のサーバーに分散されることが多くなります。分散とは、M と N の値が直線的に増加することを意味し、非同期と同期のパフォーマンスの差も増幅します。つまり、IO は高価ですが、分散 IO はさらに高価です。
リソース割り当て
シングルスレッド同期IOrrreee
マルチスレッドプログラミング
rrreee
ノードの非同期IO
rrreee
2. ブロッキング I/O とノンブロッキング I/O
イベント ループ <code>観察
リクエスト オブジェクト
。 🎜🎜実際、ノードの非同期 IO はスレッド プール テクノロジーを使用します。非同期 IO が開始されると、IO 操作は実行のためにスレッド プールにスローされ、IO の実行が完了した後、メインスレッドが他の操作を実行し続けます。スレッド間通信を通じてメインスレッドに通知され、スレッドがコールバックを実行します。 🎜🎜IO スレッドは、具体的には Libuv
によって実装されます (Linux
は libeio
によって実装されます。window
の下には によって実装されます) IOCP (特定の実装) によって管理されるスレッド プールによって制御され、本質的にマルチスレッドです。つまり、<code>スレッド プール
と ブロッキング IO
は、非同期 IO
をシミュレートするために使用されます。 🎜🎜🎜🎜🎜🎜非同期IOの原理🎜🎜🎜IOが発生すると、それをスレッドプール内のIOスレッドに入れ、そのIOスレッド上でタスクを実行させます。IOスレッドはブロッキングIOモードで実行されます。その後、メイン スレッドで実行を継続します。別の IO タスクが見つかった場合は、そのタスクをスレッド プールに入れて、別の IO スレッド (ブロック IO モード) で実行すると、メイン スレッドは実行を継続します。 🎜🎜上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。 🎜🎜関連する推奨事項: 🎜🎜🎜Nodeモジュールの仕組みの分析について🎜🎜🎜🎜🎜Nodeの基本概念の紹介🎜🎜🎜以上がノード非同期 I/O の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。