วิธีสร้างเธรดใน nodejs


91

มีวิธีใดบ้างในการสร้างเธรดสำหรับการรันหลาย ๆ วิธีในแต่ละครั้ง

ด้วยวิธีนี้หากวิธีใดล้มเหลวระหว่างเธรดอื่น ๆ ทั้งหมดควรถูกฆ่า

คำตอบ:


94

ทุกกระบวนการ node.js เป็นเธรดเดียวโดยการออกแบบ ดังนั้นในการรับเธรดหลายเธรดคุณต้องมีหลายกระบวนการ (ตามที่ผู้โพสต์อื่น ๆ ระบุไว้นอกจากนี้ยังมีไลบรารีที่คุณสามารถเชื่อมโยงได้ซึ่งจะทำให้คุณสามารถทำงานกับเธรดในโหนดได้ แต่ไม่มีความสามารถดังกล่าวหากไม่มีไลบรารีเหล่านั้น ดูคำตอบโดย Shawn Vincent อ้างอิงhttps://github.com/audreyt/node-webworker-threads )

คุณสามารถเริ่มต้นกระบวนการที่เด็กจากกระบวนการหลักของคุณเป็นที่แสดงที่นี่ในเอกสาร Node.js: http://nodejs.org/api/child_process.html ตัวอย่างเป็นสิ่งที่ดีในหน้านี้และค่อนข้างตรงไปตรงมา

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

ดูเพิ่มเติมที่: Node.js บนเครื่องมัลติคอร์


กระบวนการสามารถทำงานแบบขนานและตามลำดับได้ในเวลาเดียวกัน?
user87267867

2
กระบวนการย่อยไม่ขึ้นอยู่กับกระบวนการหลัก พวกเขามีพื้นที่หน่วยความจำ PID และเวลาดำเนินการของตนเอง ไม่แน่ใจว่าคุณหมายถึงอะไรตามลำดับ แต่ใช่มันจะทำงานแบบคู่ขนานและกำหนดเวลาแยกกันโดยระบบปฏิบัติการเพื่อดำเนินการ
Brian

วิธีการเรียกฟังก์ชันที่ผู้ใช้กำหนดว่าเป็นกระบวนการลูก?
user87267867

ฉันจะสร้างกระบวนการย่อยเพื่อเรียกใช้ฟังก์ชัน abc () ได้อย่างไร {}
user87267867

2
ไม่ทราบว่าห้องสมุดนั้น แต่ดูเหมือนว่าตามความคิดเห็นของ Alex Mills คุณสามารถทำงานเธรดใน Node ได้ คำถามต่อไปคือคุณควร . . โหนดได้รับการออกแบบตั้งแต่พื้นฐานจนถึงโปรแกรมเมอร์อิสระจากความซับซ้อนที่มาพร้อมกับเธรด แต่ให้ประสิทธิภาพประเภทเดียวกันสำหรับการบล็อก I / O ฉันจะแก้ไขคำตอบของฉันในบัญชีสำหรับข้อเท็จจริงที่ว่าเป็นไปได้โดยใช้ไลบรารีที่อ้างอิง
Brian

34

นอกจากนี้ยังมีอย่างน้อยหนึ่งไลบรารีสำหรับทำเธรดเนทีฟจากภายใน Node.js: node-webworker-threads

https://github.com/audreyt/node-webworker-threads

โดยพื้นฐานแล้วจะใช้Web Worker browser APIสำหรับ node.js


3
สิ่งนี้ควรจะถูกต้อง คำตอบที่บอกว่าโหนดสามารถเกิดได้เฉพาะกระบวนการเท่านั้น แต่ไม่ใช่เธรดนั้นผิด
Alexander Mills

20

จากโหนด 10.5 มีตอนนี้คือการสนับสนุนหลายเธรดแต่มันคือการทดลอง หวังว่าสิ่งนี้จะมั่นคงในไม่ช้า

ชำระเงินทรัพยากรต่อไปนี้:


อัปเดต :

ตั้งแต่โหนดv11.7.0เป็นต้นไปคุณไม่จำเป็นต้องใช้--experimental-workerแฟล็

บันทึกประจำรุ่น: https://nodejs.org/en/blog/release/v11.7.0/


9

คุณสามารถรับมัลติเธรดโดยใช้ Napa.js

https://github.com/Microsoft/napajs

"Napa.js เป็นรันไทม์ JavaScript แบบมัลติเธรดที่สร้างขึ้นบน V8 ซึ่งเดิมออกแบบมาเพื่อพัฒนาบริการที่มีการวนซ้ำสูงพร้อมประสิทธิภาพที่ไม่ถูกบุกรุกใน Bing เมื่อมีการพัฒนาเราพบว่ามีประโยชน์ในการเสริม Node.js ในงานที่เชื่อมต่อกับ CPU ด้วยความสามารถในการเรียกใช้ JavaScript ใน V8 หลายตัวแยกและสื่อสารระหว่างกัน Napa.js จะแสดงเป็นโมดูล Node.js ในขณะที่สามารถฝังในกระบวนการโฮสต์ได้โดยไม่ต้องพึ่งพา Node.js "



3

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

เนื่องจากมัลติเธรดและ Node.js เป็นหัวข้อที่ซับซ้อนและมีการพูดคุยกันอย่างกว้างขวางจึงค่อนข้างยากที่จะหาแพ็คเกจที่เหมาะกับความต้องการเฉพาะของฉัน สำหรับบันทึกสิ่งเหล่านี้ไม่ได้ผลสำหรับฉัน :

  • คนงานตัวเล็ก ๆอนุญาตให้คนงานวางไข่ แต่ดูเหมือนว่าพวกเขาจะแชร์วนข้อความเดียวกัน (แต่อาจเป็นเพราะฉันทำอะไรผิด - เธรดมีเอกสารเพิ่มเติมทำให้ฉันมั่นใจว่ามันใช้กระบวนการหลายอย่างจริงๆดังนั้นฉันจึงดำเนินต่อไปจนกว่ามันจะได้ผล)
  • webworker-threadsไม่อนุญาตให้ใช้requireโมดูลสำหรับคนงานที่ฉันต้องการ

และสำหรับผู้ที่ถามว่าทำไมฉันถึงต้องการมัลติเธรดจริง : สำหรับแอปพลิเคชันที่เกี่ยวข้องกับ Raspberry Pi และอินเทอร์รัปต์ เธรดหนึ่งกำลังจัดการการขัดจังหวะเหล่านั้นและอีกเธรดหนึ่งจะดูแลการจัดเก็บข้อมูล (และอื่น ๆ )


1
ฉันขอขอบคุณสำหรับความคิดที่ดีที่ใส่ไว้ในคำตอบนี้!
MLissCetrus

3

nodejs 10.5.0 ปล่อยได้ประกาศ multithreading ใน Node.js คุณลักษณะนี้ยังอยู่ระหว่างการทดลอง ขณะนี้มีโมดูลworker_threadsใหม่

คุณสามารถเริ่มใช้เธรดถ้าคุณทำงานNode.js v10.5.0 หรือสูงกว่าแต่นี้เป็นAPI ทดลอง ไม่สามารถใช้งานได้ตามค่าเริ่มต้นคุณต้องเปิดใช้งานโดยใช้  --experimental-workerเมื่อเรียกใช้ Node.js

นี่คือตัวอย่างที่เปิดใช้งานES6และworker_threadsซึ่งทดสอบบนเวอร์ชัน 12.3.1

//package.json

  "scripts": {
  "start": "node  --experimental-modules --experimental- worker index.mjs"
  },

ตอนนี้คุณจำเป็นต้องนำเข้าคนงานจากWORKER_THREADS หมายเหตุ: คุณต้องประกาศไฟล์js ของคุณด้วยนามสกุล ".mjs"สำหรับการรองรับ ES6

//index.mjs
import { Worker } from 'worker_threads';

const spawnWorker = workerData => {
    return new Promise((resolve, reject) => {
        const worker = new Worker('./workerService.mjs', { workerData });
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', code => code !== 0 && reject(new Error(`Worker stopped with 
        exit code ${code}`)));
    })
}

const spawnWorkers = () => {
    for (let t = 1; t <= 5; t++)
        spawnWorker('Hello').then(data => console.log(data));
}

spawnWorkers();

ในที่สุดเราก็สร้าง workerService.mjs

//workerService.mjs
import { workerData, parentPort, threadId } from 'worker_threads';

// You can do any cpu intensive tasks here, in a synchronous way
// without blocking the "main thread"
parentPort.postMessage(`${workerData} from worker ${threadId}`);

เอาท์พุต:

เริ่มการทำงาน npm

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5

2
นี่คือบทความของคุณ: blog.logrocket.com/… ?
บริการ

ไม่.. ไม่ใช่ ... ฉันอ้างย้อนเวลากลับไป
priyeshdkr



0

คุณอาจกำลังมองหาPromise.race(โซลูชันการแข่งรถ I / O แบบเนทีฟไม่ใช่เธรด)

สมมติว่าคุณ (หรือคนอื่น ๆ ที่ค้นหาคำถามนี้) ต้องการแข่งขันเธรดเพื่อหลีกเลี่ยงความล้มเหลวและหลีกเลี่ยงค่าใช้จ่ายในการดำเนินการ I / O นี่เป็นวิธีที่ง่ายและเป็นธรรมชาติในการทำให้สำเร็จ (ซึ่งไม่ใช้เธรด) โหนดได้รับการออกแบบให้เป็นเธรดเดียว (ค้นหาลูปเหตุการณ์) ดังนั้นหลีกเลี่ยงการใช้เธรดหากเป็นไปได้ หากสมมติฐานของฉันถูกต้องฉันขอแนะนำให้คุณใช้Promise.raceกับsetTimeout(ตัวอย่างในลิงค์) ด้วยกลยุทธ์นี้คุณจะแข่งขันรายการของสัญญาซึ่งแต่ละรายการจะลองใช้การดำเนินการ I / O และปฏิเสธคำสัญญาหากมีข้อผิดพลาด Promise.raceคำสั่งอย่างต่อเนื่องหลังจากที่การแก้ปัญหาแรก / ปฏิเสธซึ่งดูเหมือนว่าจะเป็นสิ่งที่คุณต้องการ หวังว่านี่จะช่วยใครสักคน!


2
สิ่งนี้ไม่เกี่ยวข้องกับเธรด พวกเขาทั้งหมดทำงานในเธรดเดียวกัน
Evan Carroll

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

ดูเหมือนว่าจะตอบเกณฑ์ OP: "หากวิธีใดล้มเหลวระหว่างเธรดอื่น ๆ ทั้งหมดควรถูกฆ่า" ดังนั้นฉันจึงคิดว่ามันเกี่ยวข้อง
smileham

Promise.race ดำเนินการสัญญาทั้งหมดตามลำดับสลับจากที่หนึ่งไปเป็นอีกแบบหนึ่งในกรณีของการดำเนินการแบบอะซิงโครนัส (หรือรอในกรณีของฟังก์ชัน async)
Nagabhushan Baddi

0

Node.js ไม่ใช้เธรด ตามที่นักประดิษฐ์กล่าวว่าเป็นคุณลักษณะสำคัญ ในช่วงเวลาของการประดิษฐ์เธรดช้ามีปัญหาและยาก Node.js ถูกสร้างขึ้นจากการตรวจสอบทางเลือก single-core ที่มีประสิทธิภาพ ผู้ที่ชื่นชอบ Node.js ส่วนใหญ่ยังคงอ้างถึงอาร์กิวเมนต์เก่า ๆ ราวกับว่าเธรดไม่ได้รับการปรับปรุงในช่วง 50 ปีที่ผ่านมา

อย่างที่ทราบกันดีว่า Node.js ใช้ในการรัน JavaScript ภาษา JavaScript ได้พัฒนาขึ้นในช่วงหลายปีที่ผ่านมา ตอนนี้มีวิธีการใช้หลายคอร์ - นั่นคือสิ่งที่เธรดทำ ดังนั้นด้วยความก้าวหน้าใน JavaScript คุณสามารถทำมัลติทาสก์แบบมัลติคอร์ในแอปพลิเคชันของคุณได้ user158 ชี้ให้เห็นว่า Node.js กำลังเล่นกับมันเล็กน้อย ฉันไม่รู้อะไรเกี่ยวกับเรื่องนั้น แต่ทำไมต้องรอให้ Node.js อนุมัติสิ่งที่ JavaScript นำเสนอ

Google สำหรับมัลติเธรด JavaScript แทนมัลติเธรด Node.js คุณจะได้เรียนรู้เกี่ยวกับ Web Workers คำสัญญาและสิ่งอื่น ๆ

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