国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript 單線程不簡單.md

Lowky / 2775人閱讀

摘要:對于而言,單線程指的是它的執(zhí)行線程是單線程。對于來說,單線程不僅不是劣勢,它對于降低編程復(fù)雜度還有很重要的作用,單線程避免了多線程編程模型多線程死鎖狀態(tài)同步等問題。單線程的應(yīng)用是脆弱了,但群體的力量是強大的。

我們常聽說 JavaScript 是單線程的,那這個單線程是什么意思呢?單線程是否意味 JavaScript 存在性能缺陷呢?

在瀏覽器端,JavaScript 單線程指的是 JavaScript 的執(zhí)行線程與 UI 渲染線程共用一個線程。對于 NodeJS 而言,單線程指的是它的 JavaScript 執(zhí)行線程是單線程。雖然 JavaScript 只能單線程執(zhí)行,但 JavaScript 引擎可不是,它能夠創(chuàng)建多個線程為主線程服務(wù)。Web Worker 已經(jīng)得到大部分瀏覽器的支持,NodeJS 也擁有自己的線程池來處理 I/O 操作。無論前端還是后端,JavaScript 已經(jīng)能夠利用多個線程來提升程序性能了。

NodeJS 單線程異步 I/O 模型

NodeJS 是單線程異步 I/O 模型。換句話說,NodeJS 代碼執(zhí)行占用一個線程,而代碼中的 I/O 操作則是交給其它線程執(zhí)行,執(zhí)行完畢后將結(jié)果交還給主線程。

對于 NodeJS 來說,單線程不僅不是劣勢,它對于降低編程復(fù)雜度還有很重要的作用,單線程避免了多線程編程模型多線程死鎖、狀態(tài)同步等問題。而異步 I/O 避免了單線程同步編程模型的阻塞問題,使 CPU 得到更充分的使用。

NodeJS 異步 I/O 模型的實現(xiàn)離不開 libuv 層,libuv 提供了一個線程池來執(zhí)行 I/O 操作,執(zhí)行完畢后再將結(jié)果返回給執(zhí)行線程,因此 I/O 操作不會阻塞執(zhí)行線程地繼續(xù)執(zhí)行。libuv 是一個事件驅(qū)動的異步 I/O 庫,它是跨平臺的,在 *nix 平臺下,自行實現(xiàn)了線程池,在 windows 平臺采用了 IOCP,IOCP 內(nèi)部仍是線程池原理,libuv 的線程池默認為 4 個線程。接下來我們在 Linux 環(huán)境下看一看 NodeJS 的多個線程。

查看 NodeJS 多線程

首先,我們需要先編寫一個 js 腳本,寫入一個定時器使得腳本不會因為執(zhí)行完畢而被關(guān)掉。

setInterval(function () {}, 1000)

node命令執(zhí)行該腳本,開啟另一個窗口(或者把程序放后臺執(zhí)行)來查看 NodeJS 進程下的線程情況。

$ ps -a
  PID TTY          TIME CMD
16699 pts/2    00:00:00 node
16706 pts/0    00:00:00 ps
$ ps -L -p 16699
  PID   LWP TTY          TIME CMD
16699 16699 pts/2    00:00:00 node
16699 16700 pts/2    00:00:00 V8 WorkerThread
16699 16701 pts/2    00:00:00 V8 WorkerThread
16699 16702 pts/2    00:00:00 V8 WorkerThread
16699 16703 pts/2    00:00:00 V8 WorkerThread
16699 16704 pts/2    00:00:00 node

可以看到包括 V8 引擎的工作線程在內(nèi),已經(jīng)開啟了 6 個線程(MAC OS 系統(tǒng)用ps -M -p 命令)。當前,線程池還未被創(chuàng)建,只有進行 I/O 操作后,線程池才會被創(chuàng)建。在腳本中添加異步讀取文件的代碼來激活線程池。

require("fs").readFile("test.js", function () {})
setInterval(function () {}, 1000)

重新啟動腳本,可以看到,啟動的 4 個新線程正是 libuv 線程池默認的 4 個線程。

$ ps -a
  PID TTY          TIME CMD
16745 pts/2    00:00:00 node
16755 pts/0    00:00:00 ps
$ ps -L -p 16745
  PID   LWP TTY          TIME CMD
16745 16745 pts/2    00:00:00 node
16745 16746 pts/2    00:00:00 V8 WorkerThread
16745 16747 pts/2    00:00:00 V8 WorkerThread
16745 16748 pts/2    00:00:00 V8 WorkerThread
16745 16749 pts/2    00:00:00 V8 WorkerThread
16745 16750 pts/2    00:00:00 node
16745 16751 pts/2    00:00:00 node
16745 16752 pts/2    00:00:00 node
16745 16753 pts/2    00:00:00 node
16745 16754 pts/2    00:00:00 node

可以通過修改環(huán)境變量process.env.UV_THREADPOOL_SIZE(最大 128)使 NodeJS 支持更多地線程。

// js
process.env.UV_THREADPOOL_SIZE = 64
require("fs").readFile("test.js", function () {})
setInterval(function () {}, 1000)

// bash
$ ps -a
  PID TTY          TIME CMD
16782 pts/2    00:00:00 node
16852 pts/0    00:00:00 ps
$ ps -L -p 16782 | wc -l
71

重新執(zhí)行腳本,可以看到減去第一行和 6 個初始線程,有 64 個線程在為 NodeJS 的異步 I/O 服務(wù)。

高并發(fā)和高可用

JavaScript 是單線程,但 JavaScript 引擎能夠創(chuàng)建多個線程來服務(wù)與主線程,而 NodeJS 的主線程就像一個調(diào)度員,它能夠?qū)?I/O 操作,例如網(wǎng)絡(luò)請求,分發(fā)給其它線程進行處理,在通過事件機制將結(jié)果返回給主線程,因此,NodeJS 編寫的服務(wù)器能夠支持極大的并發(fā)量,這也是 NodeJS 的優(yōu)勢所在。NodeJS 主線程不宜進行大量地計算,因為這會阻塞主線程的運行。所以一般來說,NodeJS 適合 I/O 密集型場景,不適合 CPU 密集型場景。

除了多線程的支持,NodeJS 還提供 child_process 和 cluster 接口允許用戶創(chuàng)建很多子進程來處理任務(wù)。單線程的 NodeJS 應(yīng)用是脆弱了,但群體的力量是強大的。多進程、多線程的 NodeJS 才是服務(wù)器性能和穩(wěn)定性的保證。

參考資料

http://docs.libuv.org/en/latest/threadpool.html

《深入淺出 NodeJS》

https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html

https://nodejs.org/dist/latest-v8.x/docs/api/cluster.html

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85022.html

相關(guān)文章

  • Node.js 指南(阻塞與非阻塞概述)

    摘要:標準庫中的所有方法都提供非阻塞的異步版本,并接受回調(diào)函數(shù),某些方法還具有對應(yīng)的阻塞方法,其名稱以結(jié)尾。比較代碼阻塞方法同步執(zhí)行,非阻塞方法異步執(zhí)行。 阻塞與非阻塞概述 此概述介紹了Node.js中阻塞與非阻塞調(diào)用之間的區(qū)別,此概述將引用事件循環(huán)和libuv,但不需要事先了解這些主題,假設(shè)讀者對JavaScript語言和Node.js回調(diào)模式有基本的了解。 I/O主要指與libuv支持的...

    zebrayoung 評論0 收藏0
  • 【Node Hero】3. 理解異步編程

    摘要:異步編程在傳統(tǒng)編程實踐中,大多數(shù)操作都是同步發(fā)生的。中的異步編程異步是一種輸入輸出處理的形式,它允許在傳輸完成之前,其它處理能繼續(xù)進行。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀事鏈接:http://www.zcfy.cc/article/1759原文:https://blog.risingstack.com/node-hero-async-programming-in-node-js/ ...

    kevin 評論0 收藏0
  • 總結(jié):JavaScript異步、事件循環(huán)與消息隊列、微任務(wù)與宏任務(wù)

    摘要:單線程異步非阻塞然后,這又牽扯到了事件循環(huán)消息隊列,還有微任務(wù)宏任務(wù)這些。此步的位置不確定某個時刻后,定時器觸發(fā)線程通知事件觸發(fā)線程,事件觸發(fā)線程將回調(diào)函數(shù)加入消息隊列隊尾,等待引擎線程執(zhí)行。 前言 Philip Roberts 在演講 great talk at JSConf on the event loop 中說:要是用一句話來形容 JavaScript,我可能會這樣: Java...

    qianfeng 評論0 收藏0
  • JavaScript異步編程原理

    摘要:一異步編程原理顯然,上面這種方式和銀行取號等待有些類似,只不過銀行取號我們并不知道上一個人需要多久才會完成。下面來探討下中的異步編程原理。 眾所周知,JavaScript 的執(zhí)行環(huán)境是單線程的,所謂的單線程就是一次只能完成一個任務(wù),其任務(wù)的調(diào)度方式就是排隊,這就和火車站洗手間門口的等待一樣,前面的那個人沒有搞定,你就只能站在后面排隊等著。在事件隊列中加一個延時,這樣的問題便可以得到緩解...

    lidashuang 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<