欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Node.js的多線程能力怎么做異步計(jì)算

本篇內(nèi)容介紹了“Node.js的多線程能力怎么做異步計(jì)算”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

十載的藁城網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)整合營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整藁城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“藁城網(wǎng)站設(shè)計(jì)”,“藁城網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

都說(shuō) Node.js 可以實(shí)現(xiàn)高性能的服務(wù)器,那什么是高性能呢?

所有的軟件代碼最終都是通過(guò) CPU 來(lái)跑的,能不能把 CPU 高效利用起來(lái)是區(qū)分性能高低的標(biāo)志,也就是說(shuō)不能讓它空轉(zhuǎn)。

那什么時(shí)候會(huì)空轉(zhuǎn)呢?

  • 當(dāng)程序在進(jìn)行網(wǎng)絡(luò)和磁盤的 IO 的時(shí)候,這時(shí)候 CPU 是空閑的,也就是在空轉(zhuǎn)。

  • 多核 CPU 可以同時(shí)跑多個(gè)程序,如果只利用了其中一核,那么其他核也是在空轉(zhuǎn)。

所以,要想達(dá)到高性能,就要解決這兩個(gè)問(wèn)題。

操作系統(tǒng)提供了線程的抽象,對(duì)應(yīng)代碼不同的執(zhí)行分支,都是可以同時(shí)上不同的 CPU 跑的,這是利用好多核 CPU 性能的方式。

而如果有的線程在進(jìn)行 IO 了,也就是要阻塞的等待讀寫完成,這種是比較低效的方式,所以操作系統(tǒng)實(shí)現(xiàn)了 DMA 的機(jī)制,就是設(shè)備控制器,由硬件來(lái)負(fù)責(zé)從設(shè)備到內(nèi)存的搬運(yùn),在搬完了告訴 CPU 一聲。這樣當(dāng)有的線程在 IO 的時(shí)候就可以把線程暫停掉,等收到 DMA 運(yùn)輸數(shù)據(jù)完成的通知再繼續(xù)跑。

多線程、DMA,這是利用好多核 CPU 優(yōu)勢(shì)、解決 CPU 阻塞等 IO 的問(wèn)題的操作系統(tǒng)提供的解決方案。

而各種編程語(yǔ)言對(duì)這種機(jī)制做了封裝,Node.js 也是,Node.js 之所以是高性能,就是因?yàn)楫惒?IO 的設(shè)計(jì)。

Node.js 的異步 IO 的實(shí)現(xiàn)在 libuv,基于操作系統(tǒng)提供的異步的系統(tǒng)調(diào)用,這種一般是硬件級(jí)別的異步,比如 DMA 搬運(yùn)數(shù)據(jù)。但是其中有一些同步的系統(tǒng)調(diào)用,通過(guò) libuv 封裝以后也會(huì)變成異步的,這是因?yàn)?libuv 內(nèi)有個(gè)線程池,來(lái)執(zhí)行這些任務(wù),把同步的 API 變成異步的。這個(gè)線程池的大小可以通過(guò) UV_THREADPOOL_SIZE 的環(huán)境變量設(shè)置,默認(rèn)是 4。

Node.js的多線程能力怎么做異步計(jì)算

我們?cè)诖a里調(diào)用的異步 API,很多都是通過(guò)線程來(lái)實(shí)現(xiàn)的。

比如:

const fsPromises = require('fs').promises;

const data = await fsPromises.readFile('./filename');

但是,這種異步 API 只解決了 IO 的問(wèn)題,那如何利用多核 CPU 的優(yōu)勢(shì)來(lái)做計(jì)算呢?

Node.js 在 10.5 實(shí)驗(yàn)性的引入(在 12 正式引入)了 worker_thread 模塊,可以創(chuàng)建線程,最終用多個(gè) CPU 跑,這是利用多核 CPU 的做計(jì)算的方式。

異步 API 可以利用多線程做 IO,而 worker_thread 可以創(chuàng)建線程做計(jì)算,用于不同的目的。

要聊清楚 worker_thread,還得從瀏覽器的 web worker 聊起。

瀏覽器的 web worker

瀏覽器也同樣面臨不能利用多核 CPU 做計(jì)算的問(wèn)題,所以 html5 引入了 web worker,可以通過(guò)另一個(gè)線程做計(jì)算。

<!DOCTYPE html>
<html>
<head></head>
<body>
    <script>
        (async function () {
            const res = await runCalcWorker(2, 3, 3, 3);
            console.log(res);
        })();

        function runCalcWorker(...nums) {
            return new Promise((resolve, reject) => {
                const calcWorker = new Worker('./webWorker.js');
                calcWorker.postMessage(nums)
                calcWorker.onmessage = function (msg) {
                    resolve(msg.data);
                };
                calcWorker.onerror = reject;
            });
        }
    </script>

</body>
</html>

我們創(chuàng)建一個(gè) Worker 對(duì)象,指定跑在另一個(gè)線程的 js 代碼,然后通過(guò) postMessage 傳遞消息給它,通過(guò) onMessage 接收消息。這個(gè)過(guò)程也是異步的,我們進(jìn)一步把它封裝成了 promise。

然后在 webWorker.js 里面接收數(shù)據(jù),做計(jì)算,之后通過(guò) postMessage 傳回結(jié)果。

// webWorker.js
onmessage = function(msg) {
    if (Array.isArray(msg.data)) {
        const res = msg.data.reduce((total, cur) => {
            return total += cur;
        }, 0);
        postMessage(res);
    }
}

這樣,我們就利用了另一個(gè) CPU 核來(lái)跑了這段計(jì)算,對(duì)寫代碼來(lái)說(shuō)和普通的異步代碼沒啥區(qū)別。但這個(gè)異步實(shí)際上不是 IO 的異步,而是計(jì)算的異步。

Node.js 的 worker thread 和 web worker 類似,我甚至懷疑 worker thread 的名字就是受 web worker 影響的。

Node.js 的 worker thread

把上面那段異步計(jì)算的邏輯在 Node.js 里面實(shí)現(xiàn)話,是這樣的:

const runCalcWorker = require('./runCalcWorker');

(async function () {
    const res = await runCalcWorker(2, 3, 3, 3);
    console.log(res);
})();

以異步的方式調(diào)用,因?yàn)楫惒接?jì)算和異步 IO 在使用方式上沒啥區(qū)別。

// runCalcWorker.js
const  { Worker } = require('worker_threads');

module.exports = function(...nums) {
    return new Promise(function(resolve, reject) {
        const calcWorker = new Worker('./nodeWorker.js');
        calcWorker.postMessage(nums);

        calcWorker.on('message', resolve);
        calcWorker.on('error', reject);
    });
}

然后異步計(jì)算的實(shí)現(xiàn)是通過(guò)創(chuàng)建 Worker 對(duì)象,指定在另一個(gè)線程跑的 JS,然后通過(guò) postMessage 傳遞消息,通過(guò) message 接收消息。這個(gè)和 web worker 很類似。

// nodeWorker.js
const {
    parentPort
} = require('worker_threads');

parentPort.on('message', (data) => {
    const res = data.reduce((total, cur) => {
        return total += cur;
    }, 0);
    parentPort.postMessage(res);
});

在具體執(zhí)行計(jì)算的 nodeWorker.js 里面,監(jiān)聽 message 消息,然后進(jìn)行計(jì)算,通過(guò)  parentPost.postMessage 傳回?cái)?shù)據(jù)。

對(duì)比下 web worker,你會(huì)發(fā)現(xiàn)特別的像。所以,我覺得 Node.js 的 worker thread 的 api 是參考 web worker 來(lái)設(shè)計(jì)的。

但是,其實(shí) worker thread 也支持在創(chuàng)建的時(shí)候就通過(guò) wokerData 傳遞數(shù)據(jù):

const  { Worker } = require('worker_threads');

module.exports = function(...nums) {
    return new Promise(function(resolve, reject) {
        const calcWorker = new Worker('./nodeWorker.js', {
            workerData: nums
        });
        calcWorker.on('message', resolve);
        calcWorker.on('error', reject);
    });
}

然后 worker 線程里通過(guò) workerData 來(lái)取:

const {
    parentPort,
    workerData
} = require('worker_threads');

const data = workerData;
const res = data.reduce((total, cur) => {
    return total += cur;
}, 0);
parentPort.postMessage(res);

因?yàn)橛袀€(gè)傳遞消息的機(jī)制,所以要做序列化和反序列化,像函數(shù)這種無(wú)法被序列化的數(shù)據(jù)就無(wú)法傳輸了。這也是 worker thread 的特點(diǎn)。

Node.js 的 worker thread 和 瀏覽器 web woker 的對(duì)比

從使用上來(lái)看,都可以封裝成普通的異步調(diào)用,和其他異步 API 用起來(lái)沒啥區(qū)別。

都要經(jīng)過(guò)數(shù)據(jù)的序列化反序列化,都支持 postMessage、onMessage 來(lái)收發(fā)消息。

除了 message,Node.js 的 worker thread 支持傳遞數(shù)據(jù)的方式更多,比如還有 workerData。

但從本質(zhì)上來(lái)看,兩者都是為了實(shí)現(xiàn)異步計(jì)算,充分利用多核 CPU 的性能,沒啥區(qū)別。

總結(jié)

高性能的程序也就是要充分利用 CPU 資源,不要讓它空轉(zhuǎn),也就是 IO 的時(shí)候不要讓 CPU 等,多核 CPU 也要能同時(shí)利用起來(lái)做計(jì)算。操作系統(tǒng)提供了線程、DMA的機(jī)制來(lái)解決這種問(wèn)題。Node.js 也做了相應(yīng)的封裝,也就是 libuv 實(shí)現(xiàn)的異步 IO 的 api,但是計(jì)算的異步是 Node 12 才正式引入的,也就是 worker thread,api 設(shè)計(jì)參考了瀏覽器的 web worker,傳遞消息通過(guò) postMessage、onMessage,需要做數(shù)據(jù)的序列化,所以函數(shù)是沒法傳遞的。

從使用上來(lái)看異步計(jì)算、異步 IO 使用方式一樣,但是異步 IO 只是讓 cpu 不同阻塞的等待 IO 完成,異步計(jì)算是利用了多核 CPU 同時(shí)進(jìn)行并行的計(jì)算,數(shù)倍提升計(jì)算性能。

“Node.js的多線程能力怎么做異步計(jì)算”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

本文題目:Node.js的多線程能力怎么做異步計(jì)算
網(wǎng)站地址:http://aaarwkj.com/article48/jjhhep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)網(wǎng)站導(dǎo)航、搜索引擎優(yōu)化品牌網(wǎng)站制作、網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)
少妇互射视频免费视频| 丰满人妻二区三区性色| 亚洲天堂av日韩在线| 国产高清不卡一区二区| 日韩爱视频一区二区| 亚洲超清av在线播放一区二区| 91香蕉伊人综合久久麻豆| 日本免费一区二区三区的电影啊| 日韩欧美国产一区二区精品 | 成人18禁视频免费看| 午夜激情视频免费国产| 国产综合欧美日韩在线91| 91成人精品永久在线观看| 亚洲伊人av第一页在线观看| 91在线国产精品视频| 久久视热频这里只有精品| 在线最新亚洲日本韩国| 亚洲激情久热中文字幕| 青青草青青草在线观看视频| 午夜精品人妻一区二区| 久久国产欧美日韩精品| 日韩中文字幕在线乱码| 国产又猛又黄又爽无遮挡| 国产亚洲欧美久久精品| 在线观看免费视频成人播放| 日韩一区二区三区高清免费视频成人| 亚洲另类视频一区二区| 久久久久久亚洲精品人妻| 一本大道东京热无码AⅤ片| 久久免费观看性生活片| 二区三区在线欧美日韩| 素人人妻一区二区三区| 欧美日韩国产精品高清| 青草成人在线视频观看| 操你啦夜夜操狠狠躁天天爽| 国产精品18禁一区二区三区| 欧美丰满老妇性猛交| 日韩成人在线高清视频| av天堂午夜在线观看| 国产深夜福利在线观看| 91在线看片国产免费观看|