Mengapa anda katakan Node.js tidak berbenang tunggal sepenuhnya? Bagaimana untuk memahami? Artikel berikut akan membincangkannya dengan anda, saya harap ia akan membantu anda!
Saya percaya semua orang tahu bahawa nod ialah program satu benang yang menggunakan Gelung Acara untuk mencapai berbilang mata wang. Malangnya ini tidak sepenuhnya betul.
Jadi mengapa Node.js bukan program satu benang sepenuhnya?
Semua Javsacript, V8 dan gelung peristiwa yang kami tulis sendiri dijalankan dalam urutan yang sama, yang merupakan utas utama .
Hei, bukankah ini bermakna nod itu berbenang tunggal?
Tetapi mungkin anda tidak tahu bahawa nod mempunyai banyak modul dengan kod C di belakangnya.
Walaupun nod tidak mendedahkan pengguna kepada kebenaran untuk mengawal benang, C boleh menggunakan berbilang benang.
Jadi bila nod akan menggunakan multi-threading?
Jika kaedah nod memanggil kaedah segerak C di belakang tabir, kaedah itu akan dijalankan dalam urutan utama.
Jika kaedah nod memanggil kaedah tak segerak C di belakang tabir, kadangkala kaedah itu tidak dijalankan dalam utas utama.
Cakap itu murah, tunjukkan kodnya.
Di sinicrypto
Banyak modul berkaitan ditulis dalam C. Program berikut ialah fungsi untuk mengira cincang, yang biasanya digunakan untuk menyimpan kata laluan.
import { pbkdf2Sync } from "crypto"; const startTime = Date.now(); let index = 0; for (index = 0; index < 3; index++) { pbkdf2Sync("secret", "salt", 100000, 64, "sha512"); const endTime = Date.now(); console.log(`${index} time, ${endTime - startTime}`); } const endTime = Date.now(); console.log(`in the end`);
Masa keluaran,
0 time, 44 1 time, 90 2 time, 134 in the end
Anda boleh melihat bahawa ia mengambil masa kira-kira 45ms setiap kali dan kod dilaksanakan secara berurutan pada urutan utama.
Beri perhatian kepada siapa keluaran akhir? Ambil perhatian bahawa cincang di sini mengambil masa ~45ms pada CPU saya.
import { cpus } from "os"; import { pbkdf2 } from "crypto"; console.log(cpus().length); let startTime = console.time("time-main-end"); for (let index = 0; index < 4; index++) { startTime = console.time(`time-${index}`); pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => { if (err) throw err; console.timeEnd(`time-${index}`); }); } console.timeEnd("time-main-end");
Masa keluaran,
time-main-end: 0.31ms time-2: 45.646ms time-0: 46.055ms time-3: 46.846ms time-1: 47.159ms
Lihat di sini , utas utama berakhir lebih awal, tetapi masa untuk setiap pengiraan ialah 45ms Anda mesti tahu bahawa masa yang diperlukan untuk CPU mengira cincang ialah 45ms. Nod di sini pasti menggunakan berbilang utas untuk pengiraan cincang.
Jika saya menukar bilangan panggilan di sini kepada 10, maka masanya adalah seperti berikut. Sekali lagi, terbukti bahawa nod pasti menggunakan berbilang benang untuk pengiraan cincang.
time-main-end: 0.451ms time-1: 44.977ms time-2: 46.069ms time-3: 50.033ms time-0: 51.381ms time-5: 96.429ms // 注意这里,从第五次时间开始增加了 time-7: 101.61ms time-4: 113.535ms time-6: 121.429ms time-9: 151.035ms time-8: 152.585ms
Walaupun terbukti di sini, nod pastinya mendayakan pelbagai benang. Tapi masalah sikit? CPU komputer saya ialah AMD R5-5600U, yang mempunyai 6 teras dan 12 benang. Tetapi mengapa masa meningkat dari kali kelima tidak menggunakan CPU saya sepenuhnya?
Apa sebabnya?
Nod menggunakan kumpulan benang yang dipratentukan Saiz lalai kumpulan benang ini ialah 4.
eksport UV_THREADPOOL_SIZE=6
Mari kita lihat An. contoh,
import { request } from "https"; const options = { hostname: "www.baidu.com", port: 443, path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png", method: "GET", }; let startTime = console.time(`main`); for (let index = 0; index < 15; index++) { startTime = console.time(`time-${index}`); const req = request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); console.timeEnd(`time-${index}`); res.on("data", (d) => { // process.stdout.write(d); }); }); req.on("error", (error) => { console.error(error); }); req.end(); } console.timeEnd("main");
main: 13.927ms time-2: 83.247ms time-4: 89.641ms time-3: 91.497ms time-12: 91.661ms time-5: 94.677ms ..... time-8: 134.026ms time-1: 143.906ms time-13: 140.914ms time-10: 144.088ms
Atur cara utama di sini juga tamat awal Di sini saya mulakan permintaan http untuk memuat turun imej sebanyak 15 kali, dan mereka dibelanjakan Masa tidak meningkat secara eksponen dan nampaknya tidak dihadkan oleh kumpulan benang/cpu.
Kenapa? ? Adakah Node menggunakan kolam benang?
Jika kaedah C asynchronous di belakang Node akan cuba melihat jika terdapat sokongan tak segerak kernel, sebagai contoh, sila gunakan epoll (Linux) untuk rangkaian di sini Jika kernel tidak menyediakan kaedah tak segerak, Node akan menggunakan kumpulan benangnya sendiri. .
Jadi, walaupun permintaan http tidak segerak, ia dilaksanakan oleh kernel Selepas kernel selesai, C akan dimaklumkan, dan C akan memberitahu utas utama untuk mengendalikan panggilan balik.
Jadi kaedah tak segerak yang manakah dalam Node menggunakan kumpulan benang? Mana yang tidak?
Async Kernal Asli
Kolam benang
ini Ia juga merupakan titik masuk untuk kebanyakan pengoptimuman Nod.
Tetapi bagaimana ini digabungkan dengan Gelung Acara yang paling penting?
Saya percaya semua orang sudah biasa dengan gelung Acara. Gelung acara adalah seperti pengedar
Jika ia menemui program javascript biasa atau panggilan balik, ia diserahkan kepada V8 untuk diproses.
Jika kaedah penyegerakan ditulis dalam C, serahkan kepada C dan jalankannya pada utas utama.
Jika anda menemui kaedah tak segerak, bahagian belakang ditulis dalam C. Jika terdapat sokongan tak segerak kernel, ia akan diserahkan dari utas utama kepada kernel untuk pemprosesan.
Jika ia tak segerak bahagian belakang kaedah ditulis dalam C. Jika tiada sokongan tak segerak kernel, ia diserahkan dari utas utama kepada kolam benang.
Kumpulan benang dan kernel akan mengembalikan hasil ke gelung acara Jika terdapat panggilan balik javascript didaftarkan, ia akan diserahkan kepada V8 untuk diproses.
Kemudian kitaran diteruskan sehingga tiada apa-apa lagi untuk diproses.
Jadi Node bukanlah program berbenang tunggal.
Untuk lebih banyak pengetahuan berkaitan nod, sila lawati: tutorial nodejs!
Atas ialah kandungan terperinci Bagaimana untuk memahami bahawa Node.js bukanlah program satu benang sepenuhnya (analisis ringkas). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!