กระบวนการเด็ก node.js - ความแตกต่างระหว่างวางไข่และส้อม


141

นี่อาจดูเหมือนคำถามพื้นฐาน แต่ฉันไม่พบเอกสาร:

อะไรคือความแตกต่างระหว่างการฟอร์กและการวางไข่กระบวนการ node.js? ฉันได้อ่านแล้วว่าการฟอร์กเป็นกรณีพิเศษของการวางไข่ แต่อะไรคือกรณีการใช้งานที่แตกต่างกัน / การใช้งานซ้ำสำหรับการใช้งานแต่ละแบบ

คำตอบ:


216

วางไข่เป็นคำสั่งที่ออกแบบมาเพื่อรันคำสั่งระบบ เมื่อคุณรันการวางไข่คุณจะส่งคำสั่งระบบที่จะทำงานในกระบวนการของตัวเอง แต่จะไม่รันโค้ดเพิ่มเติมใด ๆ ภายในกระบวนการโหนดของคุณ คุณสามารถเพิ่ม listeners สำหรับกระบวนการที่คุณวางไข่เพื่ออนุญาตให้โค้ดของคุณโต้ตอบกับกระบวนการที่เกิดใหม่ แต่ไม่มีการสร้างอินสแตนซ์ V8 ใหม่ (เว้นแต่แน่นอนว่าคำสั่งของคุณคือคำสั่ง Node อื่น แต่ในกรณีนี้คุณควรใช้ fork!) และ โมเดอร์โหนดของคุณหนึ่งสำเนาเท่านั้นที่แอ็คทีฟบนตัวประมวลผล

Fork เป็นตัวอย่างพิเศษของการวางไข่ซึ่งทำงานเป็นตัวอย่างใหม่ของเครื่องยนต์ V8 หมายความว่าคุณสามารถสร้างคนงานหลายคนทำงานบนฐานรหัสโหนดเดียวกันหรืออาจเป็นโมดูลที่แตกต่างกันสำหรับงานเฉพาะ สิ่งนี้มีประโยชน์มากที่สุดสำหรับการสร้างกลุ่มผู้ปฏิบัติงาน แม้ว่ารูปแบบเหตุการณ์ async ของโหนดจะอนุญาตให้ใช้แกนเดียวของเครื่องได้อย่างมีประสิทธิภาพพอสมควร แต่ก็ไม่อนุญาตให้กระบวนการโหนดใช้ประโยชน์จากเครื่องมัลติคอร์ วิธีที่ง่ายที่สุดในการบรรลุเป้าหมายนี้คือการเรียกใช้โปรแกรมเดียวกันหลายชุดในโปรเซสเซอร์เดียว

กฎง่ายๆคือกระบวนการหนึ่งถึงสองโหนดต่อหนึ่งคอร์อาจจะมากกว่าสำหรับเครื่องที่มีอัตราส่วนสัญญาณนาฬิกา ram / cpu ดีกว่าหรือสำหรับกระบวนการของโหนดที่หนักหน่วงใน I / O และแสงในการทำงานของ CPU เพื่อลดเวลาหยุดทำงานของเหตุการณ์ วนกำลังรอเหตุการณ์ใหม่ อย่างไรก็ตามข้อเสนอแนะหลังคือการเพิ่มประสิทธิภาพขนาดเล็กและจะต้องมีการเปรียบเทียบอย่างระมัดระวังเพื่อให้แน่ใจว่าสถานการณ์ของคุณเหมาะสมกับความต้องการสำหรับกระบวนการ / แกนหลักจำนวนมาก คุณสามารถลดประสิทธิภาพลงได้ด้วยการสร้างคนงานมากเกินไปสำหรับเครื่องจักร / สถานการณ์จำลองของคุณ

ในที่สุดคุณสามารถใช้วางไข่ในลักษณะที่ได้ทำข้างต้นโดยการส่งคำสั่งโหนด แต่นี่อาจเป็นเรื่องงี่เง่าเพราะ fork ทำบางสิ่งเพื่อเพิ่มประสิทธิภาพกระบวนการสร้างอินสแตนซ์ V8 เพียงแค่ทำให้ชัดเจนว่าในที่สุดไข่วางบนโลกไซเบอร์ส้อม ทางแยกเป็นเพียงที่ดีที่สุดสำหรับกรณีนี้และมีประโยชน์มากกรณีใช้

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback


@ChrisCM ถ้าฉันใช้สมมุติvar child = require('child_process').fork('child.js');ตัวอย่างเช่นในแอพหลักของฉันตอนนี้ฉันจะมี 2 คอร์แยกกันทำงาน ถ้าฉันต้องทำงานหนักสำหรับลูปใน child.js (โปรเซส) ฉันจะใช้ประโยชน์จากคอร์มากขึ้นเพื่อใช้พาวเวอร์ child.js ใช่ไหม? การใช้งาน cpu นั้นจะส่งผลกระทบต่อแกนแอปหลักของฉันหรือไม่
NiCk Newman

2
มันเป็นไปไม่ได้ที่จะทำอะไรกับซีพียูโดยไม่ทำสิ่งอื่นใด การตั้งเวลาการใช้งานแคชที่ใช้ร่วมกันการรับส่งข้อมูลบัส ฯลฯ อย่างไรก็ตามควรใช้ประโยชน์จากคอร์ที่แยกต่างหากและปล่อยให้ลูปการรันหลักของคุณไม่ได้รับผลกระทบมากที่สุด ในขณะที่ไม่มีผลกระทบเชิงลบอย่างรุนแรงที่คุณคาดหวังว่าจะมีสองกระบวนการทำงานบนโปรเซสเซอร์แกนเดียว ณ จุดนี้มันขึ้นอยู่กับระบบปฏิบัติการและการตั้งค่าฮาร์ดแวร์เพื่อเพิ่มประสิทธิภาพอย่างเหมาะสม การตั้งค่าที่แตกต่างกันอาจให้ผลลัพธ์ที่แตกต่างกัน
ChrisCM

@ChrisCM ใช่ฉันใช้ MonsterLoop ทั่วโลกเพื่อซิงโครไนซ์การกำหนดตำแหน่งสัตว์ประหลาดและวัตถุที่มันวนซ้ำนั้นสามารถมีได้มากถึง 5,000 ปุ่ม ฉันวนซ้ำทุก ๆ 2 วินาทีและดูเหมือนว่าจะตัดการใช้หน่วยความจำหลายร้อยตัวออกจากซีพียูของฉัน (เกมหลัก) ฉันอยากจะทำแบบนี้แทนการจัดกลุ่มที่วนซ้ำและทำให้มันใช้ xx จำนวนครั้งต่อหนึ่งคอร์ที่ฉันมี ... สำหรับความเข้าใจของคุณ ~ ตอนนี้ฉันไม่รู้ว่าควรใช้ Redis หรือ IPC ภายในหรือไม่: P
NiCk Newman

2
ขอบคุณสำหรับการพูดถึง "ทำไม" - โพสต์ทั้งหมดที่ฉันอ่านมาจนถึงตอนนี้พลาดคำอธิบายง่ายๆ
aaaaaa

@ChrisCM ในคำตอบของคุณ ".. แต่ไม่ได้รันโค้ดใด ๆ เพิ่มเติมภายในกระบวนการโหนดของคุณ .. " หมายความว่าเธรดหลักกำลังรอและไม่ประมวลผลอะไรเลย .. ถ้าใช่แล้วการใช้งานของการวางไข่ที่นี่คืออะไร .. ?
Abhi

9

TLDR

Spawn

เมื่อวางไข่จะถูกสร้างขึ้น- มันสร้างอินเตอร์เฟซการสตรีมระหว่างกระบวนการหลักและลูก

การสตรีมอินเทอร์เฟซหมายถึง - การบัฟเฟอร์ข้อมูลในรูปแบบไบนารีในONE TIME

Fork

เมื่อส้อมจะถูกสร้างขึ้น-มันจะสร้างช่องทางการสื่อสารระหว่างผู้ปกครองและกระบวนการเด็ก

ช่องทางการสื่อสารหมายถึง - การส่งข้อความ

Difference

ทั้งคู่ดูเหมือนว่าจะทำการถ่ายโอนข้อมูลเดียวกันยกเว้นด้านล่างแตกต่างกัน

วางไข่จะมีประโยชน์เมื่อคุณต้องการบัฟเฟอร์ข้อมูลต่อเนื่องในรูปแบบไบนารี่ / การเข้ารหัสเช่น - ถ่ายโอนไฟล์วิดีโอ 1GB, รูปภาพ, ไฟล์บันทึกในONE TIME

forkจะมีประโยชน์เมื่อคุณต้องการส่งข้อความ เช่น - JSONหรือXMLการรับส่งข้อมูล

Conslusion

วางไข่ควรใช้สำหรับการสตรีมข้อมูลขนาดใหญ่ / ไฟล์ / ภาพจากกระบวนการวางไข่ไปยังกระบวนการ ปกครอง

ทางแยกควรใช้สำหรับการส่งข้อความ Json / Xml

  • เช่นสมมติว่ากระบวนการ 10 fork ถูกสร้างจากพาเรนต์
  • และแต่ละกระบวนการดำเนินการบางอย่าง
  • และแต่ละกระบวนการในการดำเนินการให้เสร็จจะส่งข้อความถึงผู้ปกครอง ' กระบวนการหมายเลข 4 เสร็จสิ้น ', ' กระบวนการหมายเลข 8 เสร็จสิ้น '

แล้วข้อมูลการบันทึกอย่างต่อเนื่องจากพ่อแม่สู่ลูกและในที่สุดก็อยู่ในไฟล์
Esqarrouth

1
@Esqarrouth คุณต้องระบุว่าจะเป็นแบบต่อเนื่องหรือส่งข้อความ และคุณใช้คำว่า "การบันทึกอย่างต่อเนื่อง" ฉันเชื่อว่าคุณจะต้องเขียนลงในบันทึก (JSON) กับเด็กถ้าใช่ให้ใช้FORKอย่างอื่นถ้าคุณมีกลุ่มข้อมูลขนาดใหญ่มากที่จะถูกเก็บไว้ใช้SPAWN
vijay

5
  • spawn - child_process.spawnเปิดตัวกระบวนการใหม่ด้วยคำสั่งที่กำหนด
  • fork - เมธอดchild_process.forkเป็นกรณีพิเศษของการวาง ()เพื่อสร้างกระบวนการลูก

วิธีการวางไข่ ()

วิธีการ child_process.spawn เปิดตัวกระบวนการใหม่ด้วยคำสั่งที่กำหนด มันมีลายเซ็นดังต่อไปนี้ -

child_process.spawn(command[, args][, options])

อ่านเพิ่มเติมเกี่ยวกับตัวเลือก

วิธีการวางไข่ () ส่งคืนสตรีม (stdout & stderr) และควรใช้เมื่อกระบวนการส่งคืนปริมาณข้อมูลจำนวนมาก วางไข่ () เริ่มได้รับการตอบสนองทันทีที่กระบวนการเริ่มดำเนินการ

วิธีการแยก ()

เมธอดchild_process.forkเป็นกรณีพิเศษของการวางไข่ ()เพื่อสร้างกระบวนการโหนด มันมีลายเซ็นดังต่อไปนี้ -

 child_process.fork(modulePath[, args][, options])

เมธอด fork ส่งคืนอ็อบเจ็กต์ที่มีช่องทางการสื่อสารในตัวนอกเหนือจากการมีเมธอดทั้งหมดในอินสแตนซ์ ChildProcess ปกติ

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