NodeJs เป็นเธรดเดียวหรือไม่
Node.js เรียกใช้โค้ด JavaScript ในเธรดเดียว ซึ่งหมายความว่าโค้ดของคุณสามารถทำงานได้ครั้งละหนึ่งงานเท่านั้น แต่ Node.js นั้นทำงานแบบมัลติเธรดและมีเธรดที่ซ่อนอยู่ผ่านไลบรารี `libuv` ซึ่งจัดการการดำเนินการ I/O เช่น การอ่านไฟล์จากดิสก์หรือคำขอเครือข่าย ด้วยการใช้เธรดที่ซ่อนอยู่ Node.js มีวิธีการแบบอะซิงโครนัสที่ช่วยให้โค้ดของคุณสร้างคำขอ I/O โดยไม่ปิดกั้นเธรดหลัก
Node.js แนะนำโมดูล worker-threads ให้กับเรา โมดูลนั้นอนุญาตให้สร้างเธรดและเรียกใช้งาน Javascript พร้อมกัน หากเธรดทำงานเสร็จสิ้น มันจะส่งข้อความไปยังเธรดหลักที่มีผลลัพธ์ เพื่อให้เราสามารถใช้เธรดนั้นในเธรดหลักได้ เธรดผู้ปฏิบัติงานไม่ปิดกั้นเธรดหลัก ดังนั้น เราสามารถแบ่งและแจกจ่ายงานของเราไปยังหลายพาร์เพื่อเพิ่มประสิทธิภาพ
ลองทำตัวอย่างและดูให้ละเอียดยิ่งขึ้น
เรากำลังสร้างโครงการ Nodejs และติดตั้ง Express framework
mkdir multiple-thread
cd multiple-thread
npm init -y
npm install express
ประการแรกมีกระบวนการและเธรด เราควรรู้ความแตกต่างระหว่างพวกเขา
กระบวนการคืออะไร?
กระบวนการกำลังเรียกใช้โปรแกรมในระบบปฏิบัติการ สามารถดำเนินการได้ครั้งละหนึ่งงาน
มาดูกระบวนการให้ละเอียดยิ่งขึ้น สร้างไฟล์ JS และบันทึกกระบวนการ
//ex-process.js
const processName = process.argv.slice(2)[0]
let count = 0;
while(true){
count++;
if(count === 3333 || count=== 6666){
console.log(`${processName}: ${count}`)
}
}
node ex-process.js FirstEx &
// & symbol means the Node program to run in the background, so we can use
our teminal for other works
Output
[1] 82942
FirstEx: 3333
FirstEx: 6666
ps |grep node
Output
82942 ttys001 2:38.85 node ex-process.js FirstEx
83105 ttys001 0:00.00 grep node
เธรดเป็นวิธีที่ค่อนข้างเบาในการปรับใช้เส้นทางการดำเนินการหลายเส้นทางภายในแอปพลิเคชัน ในระดับระบบ โปรแกรมจะทำงานเคียงข้างกัน โดยระบบจะจัดสรรเวลาดำเนินการให้กับแต่ละโปรแกรมตามความต้องการและความต้องการของโปรแกรมอื่นๆ
ลองรหัส Express Server ด้วยเส้นทางที่ไม่ปิดกั้นและเส้นทางที่ปิดกั้น
มาเข้ารหัสเส้นทางการบล็อกปกติสำหรับผู้ใช้กันเถอะ ในapp.js;
const express = require('express');
const app = express();
app.get('/hello', (req,res)=>{
res.status(200).send(`Hello`);
})
app.get('/blocking-route', (req,res)=>{
console.log('Blocking route called')
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
})
app.listen(7333, ()=> console.log('Server started on port 7333'));
มันไม่ตอบสนองจนกว่าblocking-routeจะเสร็จสิ้นและส่งการตอบกลับ
ทำไมมันไม่ตอบเราทันที?
ในตัวอย่างนี้ CPU-bound for loop จะบล็อกเธรดหลัก ในขณะที่เธรดหลักถูกบล็อก Node.js จะไม่สามารถประมวลผลข้อความค้นหาใดๆ ได้จนกว่ากระบวนการที่เชื่อมโยงกับ CPU จะสิ้นสุดลง ดังนั้นจึงไม่มีเส้นทางอื่นเช่น/helloฟังก์ชั่นในขณะที่/blocking-routeโหลดเส้นทาง
ดังนั้น หากเรามี API ที่มีGETคำขอพร้อมกันหลายพันรายการไปยังเส้นทางที่ไม่ปิดกั้น เช่น/helloคำขอเดียวที่ส่งไปยัง the /blocking-routeจะปิดกั้นเส้นทางทั้งหมดใน API ซึ่งหมายความว่าเส้นทางแอปพลิเคชันทั้งหมดไม่ตอบสนอง
จาวาสคริปต์ของ DAAA IT เราไม่สามารถใช้เธรดอื่นได้
Dudeeee ไม่ใช่แค่ JS เท่านั้น มันคือ Nodejs เราสามารถออฟโหลดงานที่ผูกกับ CPU ด้วยเธรดผู้ปฏิบัติงาน
ก่อนอื่น เราควรตรวจสอบคอร์ของเราด้วยnprocคำสั่ง
nproc
output
8
มาสร้างไฟล์ JS อื่นเช่นworker.jsชื่อขึ้นอยู่กับคุณ ในไฟล์นี้ เราทำงานที่ต้องใช้ CPU มาก
//worker.js
const { parentPort } = require("worker_threads");
let counter = 0;
console.log("Worker started");
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
parentPort.postMessage(counter);
//app.js
const express = require("express");
const { Worker } = require("worker_threads");
const app = express();
app.get("/blocking-route", async (req, res) => {
console.log("Blocking route called");
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
});
app.get("/hello", (req, res) => {
res.status(200).send(`Hello`);
});
app.get("/non-blocking-route", async (req, res) => {
console.log("Non-blocking route called");
const worker = new Worker("./worker.js");
worker.on("message", (data) => {
res.status(200).send(`result is ${data}`);
});
worker.on("error", (err) => {
res.status(404).send(` error ${err}`);
});
console.log("I am not blocked");
});
app.listen(7333, () => console.log("Server started on port 7333"));
มาเริ่มเซิร์ฟเวอร์ด้วยnode app.js. เปิดเบราว์เซอร์ของคุณและไปhttp://localhost:7333/non-blocking-routeก่อนที่จะส่งคืนการตอบกลับ ไปhttp://localhost:7333/helloที่ คุณรู้หรือไม่? เราได้รับการตอบกลับทันที ไม่มีการปิดกั้น เราไม่ได้รอให้เส้นทางอื่นโหลดเสร็จ เนื่องจากงานที่ผูกกับ CPU ถูกออฟโหลดและกำลังทำงานเธรดอื่น และเธรดหลักจัดการคำขอทั้งหมด เราสามารถใช้คนงานจำนวนมากขึ้นเพื่อปรับปรุงประสิทธิภาพการทำงานของเรา ตัวอย่างเช่น ฉันมี 8 คอร์ และฉันแบ่งกระบวนการออกเป็น 8 คอร์ได้
บทสรุป
ผู้ปฏิบัติงาน (เธรด) สามารถช่วยในการทำงาน JavaScript ที่ใช้ CPU มาก ไม่เหมือนกับหรือchild_processสามารถแบ่งปันหน่วยความจำclusterworker_threads
ในบทความนี้ ฉันได้พยายามทำให้ง่ายขึ้นและอธิบายว่า Worker_threads ทำงานอย่างไร
ขอบคุณที่อ่าน





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)