本篇文章帶大家了解COW(Copy-On-Write)技術,介紹一下COW技術 Node.js 的進程創建和檔案複製的應用,希望對大家有幫助!
COW 不是乳牛,是 Copy-On-Write 的縮寫,這是複製但也不完全是複製的技術。
一般來說複製就是創建出完全相同的兩份,兩份是獨立的:
但是,有的時候複製這件事沒多大必要,完全可以重複使用之前的,這時候可以只是引用之前的那份,在寫內容的時候才去複製對應的一部分內容。這樣如果內容用於讀取的話,就免去了複製,而如果需要寫,才會真正複製部分內容來做修改。
這就叫做“寫時複製”,也就是 Copy-On-Write。
原理很簡單,但是在作業系統的記憶體管理和檔案系統中卻很常見,Node.js 裡面也因為這種技術變「懶」了。
本文我們來探究下 Copy-On-Write 在 Node.js 的進程創建和檔案複製的應用。 【推薦學習:《nodejs 教學》】
檔案複製
檔案複製這件事最常見的想法就是完全寫一份相同的文件內容到另一個位置,但是這樣有兩個問題:
- 完全寫一份相同的內容,如果同樣的文件複製了幾百次,那麼也創建相同的內容幾百次麼?太浪費硬碟空間了
- 如果寫到一半斷電了怎麼辦?覆蓋的內容如何恢復?
怎麼辦呢?這時候作業系統設計者就想到了 COW 技術。
用COW 技術實現檔案複製以後完美解決了上面兩個問題:
- 複製只是添加一個引用到之前的內容,如果不修改並不會真正複製,只有到第一次修改內容的時候才去真正複製對應的資料塊,這樣就避免了大量硬碟空間的浪費。
- 寫檔案時會先在另一個空閒磁碟區塊做修改,等修改完之後才會複製到目標位置,這樣就不會有斷電無法回滾的問題
#在Node.js 的fs.copyFile 的api 就可以使用Copy-On-Write 模式:
預設情況下,copyFile 會寫入目標文件,覆寫原內容
const fsPromises = require('fs').promises; (async function() { try { await fsPromises.copyFile('source.txt', 'destination.txt'); } catch(e) { console.log(e.message); } })();
但是可以透過第三個參數指定複製的策略:
const fs = require('fs'); const fsPromises = fs.promises; const { COPYFILE_EXCL, COPYFILE_FICLONE, COPYFILE_FICLONE_FORCE} = fs.constants; (async function() { try { await fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_FICLONE); } catch(e) { console.log(e.message); } })();
支援的flag 有3 個:
- COPYFILE_EXCL: 如果目標檔案已存在,會報錯(預設為覆寫)
- COPYFILE_FICLONE: 以copy-on-write 模式複製,如果作業系統不支援就轉為真正的複製(預設是直接複製)
- COPYFILE_FICLONE_FORCE:以copy-on-write 模式複製,如果作業系統不支援就報錯
這3個常數分別是1,2,4,可以透過位元或把它們合併之後傳入:
const flags = COPYFILE_FICLONE | COPYFILE_EXCL; fsPromises.copyFile('source.txt', 'destination.txt', flags);
Node.js支援作業系統的copy-on-write 技術,在一些場景下可以提升效能,建議使用COPYFILE_FICLONE 的方式,會比預設的方式好一些。
進程建立
fork 是常見的建立進程的方式,而它的實作就是一種 copy-on-write 技術。
我們知道,進程在記憶體中分為程式碼段、資料段、堆疊段這3 部分:
- 程式碼段:存放要執行的程式碼
- #資料段:存放一些全域資料
- 堆疊段:存放執行的狀態
如果基於該進程創建一個新的進程,那麼要複製這3 個部分記憶體。而如果這三部分記憶體是一樣的內容,那就浪費了記憶體空間。
所以 fork 並不會真正的複製內存,而是創建一個新的進程,引用父進程的內存,當做數據的修改的時候,才會真正複製該部分的內存。
這也是為什麼把進程創建叫做fork,也就是分叉,因為不完全是獨立的,只是某部分做了分叉,成了兩份,但是大部分還是一樣的。
但如果要執行的程式碼不一樣怎麼辦呢,這時候就要用 exec 了,它會創建新的程式碼片段、資料段、堆疊段、執行新的程式碼。
Node.js 裡面同樣可以用fork 和exec 的api:
fork:
const cluster = require('cluster'); if (cluster.isMaster) { console.log('I am master'); cluster.fork(); cluster.fork(); } else if (cluster.isWorker) { console.log(`I am worker #${cluster.worker.id}`); }
exec:
const { exec } = require('child_process'); exec('my.bat', (err, stdout, stderr) => { if (err) { console.error(err); return; } console.log(stdout); });
fork 是linux 程序建立的基礎,由此可見copy-on-write 技術多麼重要了。
總結
複製同樣的內容多份無疑比較浪費空間,所以作業系統在做檔案複製、行程建立時的記憶體複製的時候都採用了Copy-On- Write 技術,只有真正修改的時候才會去做複製。
Node.js 支援了fs.copyFile 的flags 的設置,可以指定COPYFILE_FICLONE 來使用Copy-On-Write 的方式做檔案複製,也建議大家用這種方式來節省硬碟空間,提高檔案複製的性能。
進程的fork 也是Copy-On-Write 的實現,並不會直接複製進程的程式碼段、資料段、堆疊段到新的內容,而是引用之前的,只有在修改的時候才會做真正的記憶體複製。
除此之外,Copy-On-Write 在 Immutable 的實現,在分散式的讀寫分離等領域都有許多應用。
COW 讓 Node.js 變成「懶」了,但效能卻更高了。
原文網址:https://juejin.cn/post/6999497362255118366
作者:zxg_神說要有光
更多程式設計相關知識,請造訪:程式設計入門! !
以上是淺談Node.js+COW技術進行進程建立與檔案複製的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

禪工作室 13.0.1
強大的PHP整合開發環境

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver CS6
視覺化網頁開發工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境