Nodejs ห่วงเหตุการณ์


141

มีลูปเหตุการณ์สองเหตุการณ์ภายในสถาปัตยกรรม nodejs หรือไม่

  • libev / libuv
  • เหตุการณ์ v8 javascript

ในการร้องขอ I / O โหนดคิวจะร้องขอไปยัง libeio ซึ่งจะแจ้งความพร้อมของข้อมูลผ่านเหตุการณ์โดยใช้ libev และในที่สุดเหตุการณ์เหล่านั้นจะถูกจัดการโดย v8 event loop โดยใช้ callbacks หรือไม่

โดยพื้นฐานแล้ว libev และ libeio รวมอยู่ในสถาปัตยกรรม nodejs อย่างไร

มีเอกสารใดที่ให้ภาพที่ชัดเจนของสถาปัตยกรรมภายใน nodejs หรือไม่?

คำตอบ:


175

ฉันได้อ่านซอร์สโค้ดของ node.js & v8 เป็นการส่วนตัวแล้ว

ฉันกลายเป็นปัญหาที่คล้ายกันเช่นคุณเมื่อฉันพยายามที่จะเข้าใจสถาปัตยกรรม node.js เพื่อเขียนโมดูลพื้นเมือง

สิ่งที่ฉันกำลังโพสต์ที่นี่คือความเข้าใจของฉันของ node.js และนี่อาจเป็นเรื่องเล็กน้อยเช่นกัน

  1. Libevเป็นลูปเหตุการณ์ที่ทำงานภายในจริงใน node.js เพื่อดำเนินการกับลูปเหตุการณ์แบบง่าย มันเขียนขึ้นสำหรับระบบ * nix Libev จัดเตรียมลูปเหตุการณ์ที่เรียบง่าย แต่ได้รับการปรับปรุงเพื่อให้กระบวนการทำงาน คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ libev ที่นี่

  2. LibEioเป็นไลบรารีเพื่อดำเนินการอินพุตเอาต์พุตแบบอะซิงโครนัส จะจัดการอธิบายไฟล์, รถขนข้อมูลซ็อกเก็ต ฯลฯ คุณสามารถอ่านเพิ่มเติมได้ที่นี่ที่นี่

  3. LibUvเป็นเลเยอร์นามธรรมที่ด้านบนของ libeio, libev, c-ares (สำหรับ DNS) และ iocp (สำหรับ windows asynchronous-io) LibUv ดำเนินการดูแลรักษาและจัดการ io และกิจกรรมทั้งหมดในพูลเหตุการณ์ (ในกรณีของ libeio threadpool) คุณควรตรวจสอบบทแนะนำของ Ryan Dahlบน libUv สิ่งนี้จะทำให้คุณเข้าใจได้ง่ายขึ้นเกี่ยวกับวิธีการทำงานของ libUv และจากนั้นคุณจะเข้าใจวิธีการทำงานของ node.js ที่ด้านบนของ libuv และ v8

เพื่อให้เข้าใจถึงเหตุการณ์ javascript คุณควรพิจารณาดูวิดีโอเหล่านี้

หากต้องการดูวิธีการใช้ libeio กับ node.js เพื่อสร้างโมดูล async คุณควรเห็นตัวอย่างนี้

โดยทั่วไปสิ่งที่เกิดขึ้นภายใน node.js คือ v8 loop รันและจัดการกับส่วนของจาวาสคริปต์ทั้งหมดรวมถึงโมดูล C ++ [เมื่อพวกเขากำลังทำงานในเธรดหลัก (ตามโหนดเอกสารอย่างเป็นทางการเอง เมื่ออยู่นอกเธรดหลัก libev และ libeio จะจัดการกับเธรดพูลและ libev จัดเตรียมการโต้ตอบกับลูปหลัก ดังนั้นจากความเข้าใจของฉัน node.js มี 1 เหตุการณ์วนรอบถาวร: นั่นคือเหตุการณ์ v8 ในการจัดการงาน async C ++ มันใช้ threadpool [ผ่าน libeio & libev]

ตัวอย่างเช่น:

eio_custom(Task,FLAG,AfterTask,Eio_REQUEST);

ซึ่งจะปรากฏขึ้นในโมดูลทั้งหมดมักจะเรียกใช้ฟังก์ชันTaskในเธรดพูล เมื่อเสร็จแล้วจะเรียกใช้AfterTaskฟังก์ชันในเธรดหลัก ในขณะEio_REQUESTที่ตัวจัดการการร้องขอซึ่งสามารถเป็นโครงสร้าง / วัตถุที่มีแรงจูงใจคือให้การสื่อสารระหว่างเธรดพูลและเธรดหลัก


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

1
@Raynos libuv มีจุดประสงค์เพื่อให้แน่ใจว่าเป็น x-platfousing หลายไลบรารี ใช่มั้ย ดังนั้นการใช้ libuv จึงเป็นความคิดที่ดี
ShrekOverflow

1
@Abhishek จาก Doc process.nextTick- ในลูปถัดไปรอบ ๆ ลูปเหตุการณ์ให้โทรกลับมานี้ นี่ไม่ใช่นามแฝงง่ายๆสำหรับ setTimeout (fn, 0) มันมีประสิทธิภาพมากกว่า เหตุการณ์นี้เกี่ยวข้องกับเหตุการณ์ใด วนรอบเหตุการณ์ V8
ทมิฬ

2
โปรดทราบว่า libuv ไม่ได้ใช้งานบน libevอีกต่อไป
strcat

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

20

ดูเหมือนว่าบางหน่วยงานที่กล่าวถึง (เช่น: libev ฯลฯ ) ได้สูญเสียความเกี่ยวข้องเนื่องจากความจริงที่ว่ามันได้รับในขณะที่ แต่ฉันคิดว่าคำถามยังคงมีศักยภาพที่ดี

ให้ฉันพยายามอธิบายการทำงานของโมเดลที่ขับเคลื่อนด้วยเหตุการณ์ด้วยความช่วยเหลือของตัวอย่างนามธรรมในสภาพแวดล้อม UNIX ที่เป็นนามธรรมในบริบทของโหนด ณ วันนี้

มุมมองของโปรแกรม:

  • เอ็นจินสคริปต์เริ่มต้นการเรียกใช้งานสคริปต์
  • เมื่อใดก็ตามที่พบการดำเนินการกับ CPU มันจะถูกดำเนินการแบบอินไลน์ (เครื่องจริง) โดยสมบูรณ์
  • ทุกครั้งที่พบการดำเนินการที่ผูกไว้ I / O คำขอและตัวจัดการความสมบูรณ์จะได้รับการลงทะเบียนด้วย 'เครื่องจักรเหตุการณ์' (เครื่องเสมือน)
  • ทำซ้ำการดำเนินการในลักษณะเดียวกันข้างต้นจนกว่าสคริปต์จะสิ้นสุด การทำงานของ CPU bounded - ดำเนินการแบบอินไลน์ I / O ที่ถูกผูกไว้ขอให้เครื่องจักรดังกล่าว
  • เมื่อ I / O เสร็จสมบูรณ์ผู้ฟังจะถูกเรียกกลับ

เครื่องจักรเหตุการณ์ข้างต้นเรียกว่ากรอบเหตุการณ์ลูปของ libuv AKA โหนดใช้ประโยชน์จากห้องสมุดนี้เพื่อใช้รูปแบบการเขียนโปรแกรมที่ขับเคลื่อนด้วยเหตุการณ์

มุมมองของโหนด:

  • มีหนึ่งเธรดเพื่อโฮสต์รันไทม์
  • รับสคริปต์ผู้ใช้
  • คอมไพล์มันเป็นไฟล์ดั้งเดิม [เลเวอเรจ v8]
  • โหลดไบนารีและกระโดดเข้าสู่จุดเข้า
  • โค้ดที่คอมไพล์จะประมวลผลกิจกรรม CPU ที่โยงไว้ในบรรทัดโดยใช้การโปรแกรมเบื้องต้น
  • I / O และรหัสที่เกี่ยวข้องกับตัวจับเวลาจำนวนมากมีการแรปแบบดั้งเดิม ตัวอย่างเช่นเครือข่าย I / O
  • ดังนั้นการโทร I / O จะถูกกำหนดเส้นทางจากสคริปต์ไปยังบริดจ์ C ++ พร้อมด้วยหมายเลขอ้างอิง I / O และตัวจัดการความสมบูรณ์ที่ส่งผ่านเป็นอาร์กิวเมนต์
  • โค้ดเนทีฟจะฝึกลูป libuv มันได้รับการวนรอบจัดคิวเหตุการณ์ระดับต่ำซึ่งแสดงถึง I / O และ wrapper การเรียกกลับดั้งเดิมลงในโครงสร้างลูป libuv
  • โค้ดเนทีฟจะกลับไปที่สคริปต์ - ไม่มี I / O เกิดขึ้นในขณะนี้!
  • รายการข้างต้นซ้ำหลายครั้งจนกว่ารหัสที่ไม่ใช่ I / O ทั้งหมดจะถูกดำเนินการและรหัส I / O ทั้งหมดจะถูกลงทะเบียนจะเป็น libuv
  • ในที่สุดเมื่อไม่มีสิ่งใดเหลืออยู่ในระบบที่จะดำเนินการโหนดผ่านการควบคุมไปยัง libuv
  • libuv จะถูกนำไปใช้จริงมันจะเก็บเหตุการณ์ทั้งหมดที่ลงทะเบียนแล้วทำการสอบถามระบบปฏิบัติการเพื่อให้สามารถใช้งานได้
  • ที่พร้อมสำหรับ I / O ในโหมดที่ไม่มีการปิดกั้นจะถูกหยิบขึ้นมา, I / O ที่ดำเนินการและการเรียกกลับของพวกเขาออก หนึ่งสิ่งหลังจากสิ่งอื่น.
  • ผู้ที่ยังไม่พร้อม (เช่นซ็อกเก็ตอ่านซึ่งจุดสิ้นสุดอื่นยังไม่ได้เขียนอะไร) จะถูกตรวจสอบกับระบบปฏิบัติการต่อไปจนกว่าจะพร้อมใช้งาน
  • การวนซ้ำภายในจะรักษาตัวจับเวลาที่เพิ่มขึ้นเรื่อย ๆ เมื่อแอปพลิเคชันร้องขอให้มีการโทรกลับที่เลื่อนเวลาออกไป (เช่น setTimeout) ค่าตัวจับเวลาภายในนี้จะถูกใช้เพื่อคำนวณเวลาที่เหมาะสมสำหรับการโทรกลับ

ในขณะที่ฟังก์ชั่นส่วนใหญ่รองรับในลักษณะนี้การดำเนินการบางอย่าง (เวอร์ชันอะซิงก์) ของไฟล์จะถูกดำเนินการด้วยความช่วยเหลือของเธรดเพิ่มเติมซึ่งรวมเข้ากับ libuv ได้ดี ในขณะที่การดำเนินการเครือข่าย I / O สามารถรอในความคาดหวังของเหตุการณ์ภายนอกเช่นปลายทางอื่น ๆ ตอบสนองกับข้อมูล ฯลฯ การดำเนินงานของไฟล์ต้องทำงานบางอย่างจากโหนดเอง ตัวอย่างเช่นถ้าคุณเปิดไฟล์และรอให้ fd พร้อมกับข้อมูลมันจะไม่เกิดขึ้นเนื่องจากไม่มีใครอ่านจริงๆ! ในเวลาเดียวกันถ้าคุณอ่านจากไฟล์แบบอินไลน์ในเธรดหลักอาจบล็อกกิจกรรมอื่น ๆ ในโปรแกรมและอาจทำให้เกิดปัญหาที่มองเห็นได้เนื่องจากการทำงานของไฟล์ช้ามากเมื่อเทียบกับกิจกรรม cpu ที่ถูกผูกไว้ ดังนั้นเธรดผู้ปฏิบัติงานภายใน (กำหนดค่าผ่านตัวแปรสภาพแวดล้อม UV_THREADPOOL_SIZE) จึงถูกใช้เพื่อทำงานกับไฟล์

หวังว่านี่จะช่วยได้


คุณรู้จักสิ่งเหล่านี้ได้อย่างไรคุณช่วยชี้ฉันไปยังแหล่งที่มา
Suraj Jain

18

บทนำสู่ libuv

Node.jsโครงการเริ่มต้นขึ้นในปี 2009 เป็นสภาพแวดล้อม JavaScript หลุดพ้นจากเบราว์เซอร์ ด้วยการใช้V8ของ Google และlibevของ Marc Lehmann นั้น node.js ได้รวมเอารูปแบบของ I / O ซึ่งมีรูปแบบเป็นภาษาที่เหมาะกับรูปแบบการเขียนโปรแกรม เนื่องจากวิธีที่เบราว์เซอร์สร้างรูปแบบ เมื่อ node.js ได้รับความนิยมเพิ่มขึ้นมันเป็นสิ่งสำคัญที่จะทำให้มันทำงานบน Windows ได้ แต่ libev จะทำงานบน Unix เท่านั้น Windows เทียบเท่ากับกลไกการแจ้งเตือนเหตุการณ์เคอร์เนลเช่น kqueue หรือ (e) การสำรวจความคิดเห็นคือ IOCP libuv เป็นนามธรรมรอบ libev หรือ IOCP ขึ้นอยู่กับแพลตฟอร์มให้ผู้ใช้ API ตาม libev ในรุ่นโหนด v0.9.0 ของ libuv libev ถูกลบออก

อีกรูปหนึ่งที่อธิบาย Event Loop ใน Node.js โดย @ BusyRich


อัปเดต 05/09/2017

ต่อ doc นี้ห่วงเหตุการณ์ Node.js ,

แผนภาพต่อไปนี้แสดงภาพรวมที่เรียบง่ายของลำดับเหตุการณ์ของการดำเนินการของลูป

   ┌───────────────────────┐
┌─>│        timers         
  └──────────┬────────────┘
  ┌──────────┴────────────┐
       I/O callbacks     
  └──────────┬────────────┘
  ┌──────────┴────────────┐
       idle, prepare     
  └──────────┬────────────┘      ┌───────────────┐
  ┌──────────┴────────────┐         incoming:   
           poll          │<─────┤  connections, 
  └──────────┬────────────┘         data, etc.  
  ┌──────────┴────────────┐      └───────────────┘
          check          
  └──────────┬────────────┘
  ┌──────────┴────────────┐
└──┤    close callbacks    
   └───────────────────────┘

หมายเหตุ: แต่ละกล่องจะถูกอ้างถึงเป็น "เฟส" ของลูปเหตุการณ์

ภาพรวมของเฟส

  • จับเวลา : เรียกกลับเฟสนี้ดำเนินการที่กำหนดโดยและsetTimeout()setInterval()
  • I / O callbacks : ดำเนินการเรียกกลับเกือบทั้งหมดด้วยข้อยกเว้นการเรียกกลับใกล้setImmediate()คนที่กำหนดไว้โดยจับเวลาและ
  • ไม่ได้ใช้งานเตรียม : ใช้ภายในเท่านั้น
  • โพลล์ : เรียกข้อมูลเหตุการณ์ I / O ใหม่ โหนดจะปิดกั้นที่นี่เมื่อเหมาะสม
  • ตรวจสอบ : การsetImmediate()เรียกกลับถูกเรียกที่นี่
  • ปิดการเรียกกลับ : เช่นsocket.on('close', ...)เช่น

ระหว่างการเรียกใช้เหตุการณ์ลูปแต่ละครั้ง Node.js จะตรวจสอบว่ากำลังรอ I / O อะซิงโครนัสหรือตัวจับเวลาใด ๆ และปิดการทำงานอย่างสมบูรณ์หากไม่มี


คุณได้อ้างว่า " In the node-v0.9.0 version of libuv libev was removed" แต่มีคำอธิบายเกี่ยวกับมันใน changelognodejs github.com/nodejs/node/blob/master/CHANGELOG.md และถ้า libev ถูกลบออกไปแล้วตอนนี้วิธี async I / O จะได้รับการดำเนินการใน nodejs?
intekhab

@intekhab สำหรับลิงค์นี้ฉันคิดว่า libuv ที่ใช้ libeio สามารถใช้เป็นวนรอบเหตุการณ์ใน node.js
zangw

@intekhab ฉันคิดว่า libuv กำลังใช้งานคุณสมบัติทั้งหมดที่เกี่ยวข้องกับ I / O และการลงคะแนนเลือกตั้ง ตรวจสอบที่นี่ในเอกสารนี้: docs.libuv.org/en/v1.x/loop.html
mohit kaushik

13

มีเหตุการณ์หนึ่งวนในสถาปัตยกรรม NodeJs

โมเดลเหตุการณ์ลูปของ Node.js

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

Node.js เพิ่มงานลงในคิวเหตุการณ์จากนั้นมีเธรดเดี่ยวที่รันลูปของเหตุการณ์หยิบมันขึ้นมา วนรอบเหตุการณ์คว้ารายการยอดนิยมในคิวเหตุการณ์เรียกใช้งานแล้วคว้ารายการถัดไป

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

เหตุการณ์วนรอบเริ่มที่จะพบปัญหาเมื่อแอปพลิเคชันของเราปิดกั้นการทำงานบน I / O

Node.js ใช้การเรียกกลับเหตุการณ์เพื่อหลีกเลี่ยงการรอการบล็อก I / O ดังนั้นคำร้องขอใด ๆ ที่ดำเนินการบล็อก I / O จะถูกดำเนินการบนเธรดอื่นในพื้นหลัง

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



1

ในฐานะผู้เริ่มต้นจาวาสคริปต์ฉันมีข้อสงสัยเหมือนกัน NodeJS มี 2 เหตุการณ์ลูปหรือไม่ หลังจากการค้นคว้ามานานและพูดคุยกับหนึ่งในผู้สนับสนุน V8 ฉันได้รับแนวคิดดังต่อไปนี้

  • เหตุการณ์ห่วงเป็นแนวคิดพื้นฐานของรูปแบบการเขียนโปรแกรมจาวาสคริปต์ ดังนั้นเอ็นจิ้น V8 ให้การปรับใช้เริ่มต้นสำหรับเหตุการณ์ลูปซึ่งตัวทำละลาย (เบราว์เซอร์โหนด) สามารถแทนที่หรือขยายได้ พวกคุณสามารถค้นหาการใช้งานลูปเริ่มต้นของกิจกรรมได้ที่นี่
  • ใน NodeJS มีเหตุการณ์วนครั้งเดียวเท่านั้นซึ่งมีให้โดยโหนดรันไทม์ การใช้งานลูปเหตุการณ์เริ่มต้นของ V8 ถูกแทนที่ด้วยการใช้งานลูปเหตุการณ์ NodeJS

0

pbkdf2ฟังก์ชั่นที่มีการใช้งานจาวาสคริ แต่มันเป็นจริงได้รับมอบหมายทุกงานที่จะต้องทำยัง C ++ ด้าน

env->SetMethod(target, "pbkdf2", PBKDF2);
  env->SetMethod(target, "generateKeyPairRSA", GenerateKeyPairRSA);
  env->SetMethod(target, "generateKeyPairDSA", GenerateKeyPairDSA);
  env->SetMethod(target, "generateKeyPairEC", GenerateKeyPairEC);
  NODE_DEFINE_CONSTANT(target, OPENSSL_EC_NAMED_CURVE);
  NODE_DEFINE_CONSTANT(target, OPENSSL_EC_EXPLICIT_CURVE);
  NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS1);
  NODE_DEFINE_CONSTANT(target, kKeyEncodingPKCS8);
  NODE_DEFINE_CONSTANT(target, kKeyEncodingSPKI);
  NODE_DEFINE_CONSTANT(target, kKeyEncodingSEC1);
  NODE_DEFINE_CONSTANT(target, kKeyFormatDER);
  NODE_DEFINE_CONSTANT(target, kKeyFormatPEM);
  NODE_DEFINE_CONSTANT(target, kKeyTypeSecret);
  NODE_DEFINE_CONSTANT(target, kKeyTypePublic);
  NODE_DEFINE_CONSTANT(target, kKeyTypePrivate);
  env->SetMethod(target, "randomBytes", RandomBytes);
  env->SetMethodNoSideEffect(target, "timingSafeEqual", TimingSafeEqual);
  env->SetMethodNoSideEffect(target, "getSSLCiphers", GetSSLCiphers);
  env->SetMethodNoSideEffect(target, "getCiphers", GetCiphers);
  env->SetMethodNoSideEffect(target, "getHashes", GetHashes);
  env->SetMethodNoSideEffect(target, "getCurves", GetCurves);
  env->SetMethod(target, "publicEncrypt",
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
                                         EVP_PKEY_encrypt_init,
                                         EVP_PKEY_encrypt>);
  env->SetMethod(target, "privateDecrypt",
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
                                         EVP_PKEY_decrypt_init,
                                         EVP_PKEY_decrypt>);
  env->SetMethod(target, "privateEncrypt",
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPrivate,
                                         EVP_PKEY_sign_init,
                                         EVP_PKEY_sign>);
  env->SetMethod(target, "publicDecrypt",
                 PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
                                         EVP_PKEY_verify_recover_init,
                                         EVP_PKEY_verify_recover>);

ทรัพยากร: https://github.com/nodejs/node/blob/master/src/node_crypto.cc

โมดูล Libuv มีความรับผิดชอบอื่นที่เกี่ยวข้องกับฟังก์ชันเฉพาะบางอย่างในไลบรารีมาตรฐาน

สำหรับการเรียกใช้ฟังก์ชันไลบรารีมาตรฐานด้านโหนด C ++ และ Libuv ตัดสินใจทำการคำนวณราคาแพงนอกวงเหตุการณ์ทั้งหมด

แทนที่จะใช้สิ่งที่เรียกว่าเธรดพูลเธรดพูลคือชุดของเธรดสี่ชุดที่สามารถใช้สำหรับการทำงานที่มีราคาแพงเช่นpbkdf2ฟังก์ชัน

โดยค่าเริ่มต้น Libuv จะสร้าง 4 เธรดในพูลเธรดนี้

นอกเหนือจากเธรดที่ใช้ในลูปเหตุการณ์แล้วยังมีเธรดอื่นอีกสี่เธรดที่สามารถใช้เพื่อถ่ายการคำนวณราคาแพงที่ต้องเกิดขึ้นภายในแอปพลิเคชันของเรา

ฟังก์ชันหลายอย่างที่รวมอยู่ในไลบรารีมาตรฐานโหนดจะใช้ประโยชน์จากเธรดพูลนี้โดยอัตโนมัติ pbkdf2หนึ่งฟังก์ชั่นความเป็นอยู่ของพวกเขา

การมีเธรดพูลนี้มีความสำคัญมาก

ดังนั้นโหนดจึงไม่ได้เป็นเธรดเดียวอย่างแท้จริงเนื่องจากมีเธรดอื่น ๆ ที่โหนดใช้สำหรับการทำงานบางอย่างที่มีราคาแพง

หากกลุ่มเหตุการณ์มีหน้าที่รับผิดชอบในการทำงานที่มีราคาแพงดังนั้นแอปพลิเคชันโหนดของเราก็ไม่สามารถทำอะไรได้อีก

ซีพียูของเรารันคำสั่งทั้งหมดภายในเธรดทีละตัว

ด้วยการใช้เธรดพูลเราสามารถทำสิ่งอื่น ๆ ภายในเหตุการณ์ลูปในขณะที่การคำนวณเกิดขึ้น

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