การจับทางเลือก Node JS เพื่อทำมัลติเธรด


142

ถ้าฉันเข้าใจถูกต้องโหนด JS นั้นไม่บล็อก ... ดังนั้นแทนที่จะรอการตอบสนองจากฐานข้อมูลหรือกระบวนการอื่นมันย้ายไปยังสิ่งอื่นและตรวจสอบอีกครั้งในภายหลัง

นอกจากนี้ยังเป็นเธรดเดียว

ทั้งหมดนี้หมายความว่ากระบวนการ Node JS ที่กำหนดสามารถใช้ CPU แกนเดี่ยวอย่างเต็มรูปแบบและมีประสิทธิภาพ แต่จะไม่ใช้แกนอื่น ๆ บนเครื่องเช่นเดียวกับในมันจะไม่ใช้มากกว่าหนึ่งครั้ง

หลักสูตรนี้หมายความว่า CPU อื่นยังคงสามารถใช้งานโดยกระบวนการอื่นสำหรับสิ่งต่าง ๆ เช่นฐานข้อมูล SQL หรือรูทีนย่อย CPU Heavy ที่คั่นด้วยเจตนาอื่น ๆ ตราบใดที่มันเป็นกระบวนการแยกต่างหาก

นอกจากนี้ในกรณีที่กระบวนการ Node JS มีการวนซ้ำไม่รู้จบหรือฟังก์ชั่นการทำงานที่ยาวนานกระบวนการนั้นจะไม่มีประโยชน์ในทางใด ๆ จนกว่าการวนซ้ำไม่รู้จบหรือฟังก์ชั่นการทำงานยาวจะหยุดลง (หรือกระบวนการทั้งหมดถูกฆ่า)

ถูกต้องไหม ฉันถูกต้องในการทำความเข้าใจของฉัน?


2
"โหนด" ไม่ใช่เธรดเดี่ยว เฉพาะเครื่องยนต์ JS / V8 เท่านั้นที่ทำงานในเธรดเดียว ส่วน libuv ของ NodeJS เป็นแบบมัลติเธรด ดูว่าNodeJS เป็นเธรดเดี่ยวหรือไม่
RaelB

คำตอบ:


87

ค่อนข้างถูกต้องใช่ เซิร์ฟเวอร์ node.js มีเธรดพูลภายในเพื่อให้สามารถดำเนินการบล็อกและแจ้งเตือนเธรดหลักด้วยการโทรกลับหรือเหตุการณ์เมื่อสิ่งต่าง ๆ เสร็จสมบูรณ์

ดังนั้นฉันคิดว่ามันจะทำให้การใช้งานที่ จำกัด ของคอร์อื่นสำหรับเธรดพูลตัวอย่างเช่นถ้าคุณใช้ระบบไฟล์ที่ไม่มีการปิดกั้นการอ่านสิ่งนี้น่าจะถูกนำมาใช้โดยบอกเธรดจากเธรดพูลเพื่อทำการอ่านและตั้งค่าการโทรกลับเมื่อ มันเสร็จสิ้นซึ่งหมายความว่าการอ่านอาจเกิดขึ้นบนเธรด / คอร์อื่นในขณะที่โปรแกรมหลัก node.js กำลังทำสิ่งอื่น

แต่จากมุมมองของ node.js มันเป็นแบบเธรดทั้งหมดและจะไม่ใช้มากกว่าหนึ่งคอร์โดยตรง


2
ฉันยังใหม่กับ Node.js และชื่นชมการสนทนาที่นี่ ฉันแค่อยากจะชี้ให้เห็นว่าการตั้งสมมติฐานว่าการโทรแบบไม่บล็อกนั้นได้รับการสนับสนุนจากการบล็อคการโทรแบบเธรดอาจไม่ฉลาด (ไม่ใช่ @jcoder ที่แนะนำให้ใช้รหัสสถาปนิกรอบ ๆ สมมติฐานเหล่านี้) ในกรณีนี้แม้ว่า IO จะจัดการกับเธรดแยกต่างหากด้วยการบล็อกการเรียกเธรดนั้นโดยทั่วไปจะรอบน IO ต่อไปดังนั้นมันจะไม่ใช้คอร์ / CPU อื่น ๆ รหัสเพื่อความแข็งแกร่งของเครื่องมือที่คุณใช้และไม่ต้องกังวลมากเกินไปเกี่ยวกับรายละเอียดในระดับต่ำ (จนกว่าพวกเขาจะกลายเป็นปัญหา)
wbyoung

เพื่อให้เราสามารถทำ PROSES อื่น ๆ ที่ใช้โทรกลับเช่นรหัส JavaScript บนหน้า
yussan

37

ใช่ฉันว่าความเข้าใจของคุณถูกต้องทั้งหมด บทความนี้ ( เก็บถาวร ) อธิบายถึงเหตุผลที่อยู่เบื้องหลังการออกแบบนี้ค่อนข้างดี นี่อาจเป็นย่อหน้าที่สำคัญที่สุด:

Apache มีหลายเธรด: มันจะสร้างเธรดต่อการร้องขอ (หรือกระบวนการจะขึ้นอยู่กับ conf) คุณสามารถดูว่าโอเวอร์เฮดนั้นกินหน่วยความจำได้อย่างไรเมื่อจำนวนการเชื่อมต่อพร้อมกันเพิ่มขึ้นและจำเป็นต้องมีเธรดจำนวนมากเพื่อให้บริการไคลเอนต์แบบเสมือน Nginx และ Node.js ไม่ได้เป็นแบบมัลติเธรดเนื่องจากเธรดและกระบวนการมีต้นทุนหน่วยความจำจำนวนมาก มันเป็นแบบเธรดเดียว แต่ขึ้นอยู่กับเหตุการณ์ สิ่งนี้กำจัดค่าใช้จ่ายที่สร้างโดยเธรด / กระบวนการนับพันโดยจัดการการเชื่อมต่อจำนวนมากในเธรดเดียว


บทความนี้เป็นเท็จ แม้ว่า apache mith แบบมัลติเธรดจะมีอยู่ แต่ก็ไม่เข้ากันกับการกำหนดค่าที่ใช้ทุกวัน Apache เป็นระบบมัลติโพรเซสและไม่ได้มีหลายเธรดจนถึงตอนนี้และอาจจะเป็นตลอดไป ฉันคิดว่ามันเป็นความหายนะการจัดการความหมายที่เหมาะสมของคำศัพท์เป็นเพียงความพยายามที่ดีในการซ่อนปัญหาแทนที่จะแก้ไขมัน
peterh - Reinstate Monica

1
@peterh คุณไม่สมเหตุสมผล บทความนี้ถูกต้องสมบูรณ์โดยระบุว่า apache นั้นเป็นมัลติโพรเซสหรือมัลติเธรดขึ้นอยู่กับการตั้งค่า เคสทวีคูณยิ่งแย่ลงในแง่ของการจัดการการเชื่อมต่อมากมายซึ่งเป็นเหตุผลเดียวที่ Apache ถูกกล่าวถึงในตอนแรก นอกจากนี้โมดูล PHP ที่ใช้บ่อยยังเป็นแบบมัลติเธรดเอง และในที่สุดในขณะที่ฉันไม่ใช่ผู้เชี่ยวชาญ apache ความประทับใจของฉันจากบทความอื่น ๆ ก็คือ MPM ของคนทำงานใช้กันอย่างแพร่หลาย
Michael Borgwardt

@MichaelBorgwardt ใช่ apache สามารถเป็นแบบมัลติเธรดและยังมีมัลติโพรเซสฉันไม่ได้ปฏิเสธ แต่ php ไม่สามารถใช้ร่วมกับการกำหนดค่าหลายกระบวนการและถ้าคุณจะเป็นผู้เชี่ยวชาญ apache คุณจะรู้แน่นอน โมดูล php ที่ใช้บ่อยไม่ได้เป็นแบบมัลติเธรด ข้อมูลของคุณเป็นเท็จ ฉันแนะนำให้ลองกำหนดค่าการทดสอบแล้วคุณจะเห็น มันเป็นเรื่องจริงไม่ใช่เรื่องของการอภิปรายลองมันแล้วคุณจะเห็น
peterh - Reinstate Monica

27

แม้ว่านี่จะเป็นเธรดเก่า แต่ฉันก็คิดว่าฉันจะแบ่งปันความคิดกับวิธีการใช้ประโยชน์จากคอร์นั้นในแอพ Node.JS ดังที่ Nuray Altin ได้กล่าวถึง - JXcoreสามารถทำเช่นนั้นได้

ตัวอย่างง่ายๆ:

var method = function () {
    console.log("this is message from thread no", process.threadId);
};

jxcore.tasks.runOnThread(0, method);
jxcore.tasks.runOnThread(1, method);

// this is message from thread no 1
// this is message from thread no 0

โดยค่าเริ่มต้นมีสองหัวข้อ (คุณสามารถเปลี่ยนได้ด้วยjxcore.tasks.setThreadCount())

แน่นอนว่ายังมีอะไรอีกมากมายที่คุณสามารถทำได้ด้วยภารกิจ เอกสารอยู่ที่นี่

บทความไม่กี่เรื่องที่:


13

เนื่องจากคำถามนี้ถามเมื่อเกือบ 2 ปีที่แล้ว สิ่งต่าง ๆ มีความแตกต่างหรือมีวิธีการอื่นในการแก้ปัญหามัลติเธรดใน Node.JS

ตามโพสต์บล็อกด้านล่างโดยใช้ส่วนขยาย 'งาน' ที่เข้ามาบางคนสามารถได้รับประโยชน์จากแกนที่มีอยู่อื่น ๆ โดยตรง

http://oguzbastemur.blogspot.com/2013/12/multithread-nodejs.html


1

Node.js เป็นแอปพลิเคชันแบบเธรดเดียว แต่สามารถรองรับการทำงานพร้อมกันผ่านแนวคิดของเหตุการณ์และการเรียกกลับ นี่คือวิดีโอโดยPhilip Robertsซึ่งอธิบายวิธีการทำงานของลูปใน javascript

คลิกที่นี่เพื่อดูวิดีโอ

(แทนที่จะเป็น WebAPIs จะมี C ++ APIs ใน Node.js)


2
นี่ควรเป็นความคิดเห็น
Cherniv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.