官术网_书友最值得收藏!

2.7 并行和并發

1.什么是并發

并發(Concurrency)指應用能夠交替執行不同的任務,類似于多線程,多線程并非是同時執行多個任務,而是以幾乎不可察覺的速度在多個任務之間不斷切換,以達到一種“同時執行”的效果,而事實上并不是同時執行,只是切換速度快到無法察覺。

2.什么是并行

并行(Parallellism)指應用能夠同時執行不同的任務,不同的任務是可以同時執行的。

并發與并行兩者很重要的區別是:并發是交替執行的,而并行是同時執行的。通俗地理解,并發是不同的代碼塊交替執行,并行是不同的代碼塊同時執行。如果某個系統支持兩個或者多個動作(Action)同時存在,那么這個系統就是一個并發系統。如果某個系統支持兩個或者多個動作同時執行,那么這個系統就是一個并行系統。

并行是指兩個或者多個事件在同一時刻發生。而并發是指兩個或多個事件在同一時間間隔發生。并行是在不同實體上的多個事件,并發是在同一實體上的多個事件。并行是在一臺處理器上“同時”處理多個任務,而并發是在多臺處理器上同時處理多個任務。所以并發編程的目標是充分地利用處理器的每一個核,以達到最高的處理性能。并發強調的是一起出發,并行強調的是一起執行。并發的反義是順序,并行的反義是串行。并發并行并不是互斥概念,只不過并發強調任務的抽象調度,并行強調任務的實際執行。

單線程解決高并發問題的方法就是采用非阻塞、異步編程的思想。當遇到非常耗時的IO操作時,采用非阻塞的方式繼續執行后面的代碼,并且進入事件循環,當IO操作完成時,程序會被通知IO操作已經完成。這個主要運用JavaScript的回調函數來實現。

多線程雖然也能解決高并發,但是以建立多個線程來實現,其缺點是當遇到耗時的IO操作時,當前線程會被阻塞,并且把CPU的控制權交給其他線程,這樣帶來的問題就是要非常頻繁地進行線程的上下文切換。

并發系統與并行系統這兩個定義之間的關鍵差異在于“存在”這個詞。

Node.js是單進程單線程應用程序,但是因為V8引擎提供的異步執行回調接口,通過這些接口可以處理大量的并發,所以性能非常高。Node.js是單線程且支持高并發的腳本語言,IO密集型處理是Node.js的強項,因為Node.js的IO請求都是異步的。對于異步,發出操作指令,然后就可以去做別的事情了(主線程無須等待),所有操作完成后執行回調。

【示例2-7】

let a = 1; // step1:定義變量
// step2:發出指令,然后把回調函數加入事件隊列(回調函數并沒有執行)
setTimeout(() => {
    console.log(a);
}, 0)
a = 2; // step3:賦值,回調函數沒有執行
// step4:發出指令,然后把回調函數加入異步隊列(回調函數并沒有執行)
setTimeout(() => {
    console.log(a);
}, 0)
a = 3; // step5:賦值,回調函數沒有執行
// 當所有代碼執行完畢,cpu空閑下來了,就會開始遍歷執行事件隊列里面的回調函數
// 最后輸出:3 3

異步I/O的Node.js為什么可以支持高并發?因為IO操作由Node.js的工作線程執行,Node.js底層的libuv是通過多線程的線程池來并行IO操作的,主線程不需要等待結果返回,發出指令后就去執行其他事務。

3.如何處理高并發和非阻塞請求

針對每個并發請求,服務端給請求注冊一個激發事件(I/O),并給一個回調函數(這個過程沒有阻塞新的連接請求)。按順序執行事件處理(I/O),處理完成后執行回調函數,接著執行下一個事件處理(I/O)。事件處理(I/O)的原理是什么呢?事件處理(異步I/O處理)是由Node工作線程去執行的(Node.js底層的libuv是通過多線程的線程池來并行I/O操作的),且主線程不需要等待返回,只要發出指令后就可以執行其他事件,所有操作完成后執行回調。

主站蜘蛛池模板: 陆良县| 金昌市| 融水| 平舆县| 霍林郭勒市| 叶城县| 漳平市| 马山县| 麦盖提县| 吉安县| 冷水江市| 阳曲县| 稷山县| 临汾市| 桐乡市| 钦州市| 沅陵县| 江门市| 光山县| 金门县| 曲周县| 南江县| 增城市| 灵石县| 轮台县| 余姚市| 罗田县| 桑植县| 昌平区| 常德市| 兴山县| 论坛| 汕尾市| 通榆县| 延边| 珲春市| 花莲县| 万州区| 乡宁县| 盱眙县| 城口县|