亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

單線程非阻塞IO模型是如何在Node.js中工作的

單線程非阻塞IO模型是如何在Node.js中工作的

qq_遁去的一_1 2019-06-28 15:24:12
單線程非阻塞IO模型是如何在Node.js中工作的我不是Node程序員,但我感興趣的是單線程非阻塞IO模型起作用了。在我讀了這篇文章之后理解-節點-js-事件循環我真的很困惑。它給出了一個模型的例子:c.query(    'SELECT SLEEP(20);',    function (err, results, fields) {      if (err) {        throw err;      }      res.writeHead(200, {'Content-Type': 'text/html'});      res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');      c.end();     });這里有個問題。當有兩個請求A(首先)和B,因為只有一個線程,服務器端程序將首先處理請求A:執行SQL查詢,這是一個代表I/O等待的睡眠語句。程序被放置在I/O等待時,無法執行呈現網頁后面的代碼。在等待過程中,程序會切換到請求B嗎?在我看來,由于單線程模型,無法從另一個請求切換。但是示例代碼的標題是“除了您的代碼之外,所有東西都是并行運行的”。(我不知道我是否誤解了代碼,因為我從未使用過Node。)在等待過程中節點如何切換A到B?你能解釋一下嗎單線程非阻塞IO模型以一種簡單的方式?如果你能幫我,我會很感激的。*)
查看完整描述

3 回答

?
BIG陽

TA貢獻1859條經驗 獲得超6個贊

好的,為了給出一些透視圖,讓我將node.js與Apache進行比較。

Apache是一個多線程HTTP服務器,對于服務器接收的每個請求,它都會創建一個單獨的線程來處理該請求。

另一方面,Node.js是事件驅動的,從單個線程異步處理所有請求。

當在Apache上接收到A和B時,將創建兩個處理請求的線程。每個單獨處理查詢,每個在服務頁面之前等待查詢結果。只有在查詢完成之前才能使用該頁面。由于服務器在收到結果之前無法執行其余的線程,所以查詢FETCH處于阻塞狀態。

在節點中,C.Query是異步處理的,這意味著當c.query為A獲取結果時,它跳到處理B的c.query,當結果到達A時,將結果發送回調,后者發送響應。js知道在提取完成時執行回調。

在我看來,因為它是一個單線程模型,所以無法從一個請求切換到另一個請求。

實際上,節點服務器一直都是這樣做的。要使開關(異步行為),您要使用的大多數函數都會有回調。

編輯

SQL查詢從MySQL圖書館。它實現回調樣式以及事件發射器來排隊SQL請求。它不異步執行它們,這是由內部利布夫提供非阻塞I/O抽象的線程:

  1. 打開到db的連接,就可以異步地建立連接本身。
  2. 連接db后,查詢將傳遞給服務器。查詢可以排隊。
  3. 主事件循環通過回調或事件得到完成通知。
  4. 主循環執行回調/均衡器。

對http服務器的傳入請求以類似的方式處理。內部線程體系結構如下所示:


C+線程是執行異步I/O(磁盤或網絡)的libuv線程。主事件循環在將請求分派到線程池后繼續執行。它可以接受更多的請求,因為它不等待或睡眠。SQL查詢/HTTP請求/文件系統讀取都是這樣發生的。


查看完整回答
反對 回復 2019-06-28
?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

Node.js使用利布夫幕后。利布夫有一個線程池(默認情況下大小為4)。因此,node.js使用線程實現并發。

不過你的代碼運行在單個線程上(也就是說,Node.js函數的所有回調都將在同一個線程上調用,即所謂的循環線程或事件循環)。當人們說“Node.js運行在單個線程上”時,他們實際上是在說“Node.js的回調運行在單個線程上”。


查看完整回答
反對 回復 2019-06-28
  • 3 回答
  • 0 關注
  • 874 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號