我一直在閱讀和經歷儘可能多的NodeJs代碼,但我對此有點困惑:NodeJs中單線程和非阻塞I/O操作有什麼區別?
究竟Node是單線程的意思,什麼是非阻塞I/O意思?我可以通過產生子進程來實現第一個,使用異步庫實現第二個進程。但我想澄清它是什麼意思,以及非阻塞I/O如何仍然可以減慢你的應用程序。
我一直在閱讀和經歷儘可能多的NodeJs代碼,但我對此有點困惑:NodeJs中單線程和非阻塞I/O操作有什麼區別?
究竟Node是單線程的意思,什麼是非阻塞I/O意思?我可以通過產生子進程來實現第一個,使用異步庫實現第二個進程。但我想澄清它是什麼意思,以及非阻塞I/O如何仍然可以減慢你的應用程序。
我會盡我所能解釋。
單線程意味着Node.js Javascript運行時 - 在特定的時間點 - 只執行其加載的所有代碼中的一段代碼。實際上,它從某個地方開始,並通過所有指令(調用堆棧)完成,直到完成。在執行代碼時,沒有什麼可以中斷這個過程,所有的I/O都必須等待。值得慶幸的是,大多數調用堆棧都比較短,我們在Node.js中做的很多事情都比「CPU」更重要的是「簿記」類型。
儘管單線程,任何需要很長時間的指令都會成爲系統響應的一個巨大問題。運行時一次只能做一件事,所以一切都必須等到該指令完成。如果任何「I/O」指令(例如從磁盤讀取)都會阻止執行,那麼系統在那個時候將不必要地不可用。
但謝天謝地,我們有非阻塞的I/O。
而不是等待一個文件來讀:
console.log(readFileSync(filePath))
你寫你的代碼,這樣你不等待讀取的文件:
readFile(filePath)
readFile
調用幾乎立即返回(可能在幾納秒內),因此運行時可以繼續執行接下來的指令。但是,如果readFile調用在數據讀取之前返回,那麼readFile調用就無法返回文件內容。這就是回調進來:
readFile(filePath, function(err, contents) { console.log(contents))
儘管如此,readFile
調用返回幾乎瞬間。運行時可以繼續。它將在它之前完成當前工作(所有指令都在readFile之後)。除了存儲對它的引用外,沒有任何事情是通過傳遞的函數完成的。
然後,在稍後的某個時間點(可能是10ms,100ms或1000ms以後)讀完文件時,將使用第二個參數調用該文件的全部內容。在此之前,運行時可以完成任何其他批次的工作。
現在我將闡述您對有關產卵子進程和異步庫的評論。這兩個帳戶都是錯誤的。
產生子進程是一種讓Node.js使用多於CPU內核的方法。單線程,單個Node.js沒有使用多個內核的目的。不過,如果您使用的是多核計算機,則可能需要使用所有這些核心。因此,啓動多個Node.js.流程。
異步庫不會給你非阻塞的I/O,Node.js會給你。什麼Node.js不給你自己,是一個簡單的方法來處理來自多個回調的數據。異步庫可以幫助很多。
由於我不是Node.js內部專家,我歡迎更正!
相關問題:
我發現這個鏈接是得心應手:http://blog.mixu.net/2011/02/01/understanding-the -node-js-event-loop/ –
也很有用:http://ejohn.org/blog/how-javascript-timers-work/ –