Як створити потоки в nodejs


Відповіді:


94

Кожен процес node.js є однопоточним за дизайном. Тому, щоб отримати декілька потоків, потрібно мати кілька процесів (як зазначали деякі інші плакати, є також бібліотеки, на які можна посилатись, що дасть вам можливість працювати з потоками в Node, але жодна така можливість не існує без цих бібліотек Див. Відповідь Шона Вінсента з посиланням https://github.com/audreyt/node-webworker-threads )

Ви можете запустити дочірні процеси з основного процесу, як показано тут у документації node.js: http://nodejs.org/api/child_process.html . Приклади досить хороші на цій сторінці і досить прямі.

Тоді ваш батьківський процес може спостерігати за подією закриття будь-якого запущеного процесу, а потім може змусити закрити інші процеси, які ви розпочали, щоб досягти типу однієї стратегії збій усіх зупинок, про яку ви говорите.

Також дивіться: Node.js на багатоядерних машинах


процеси можуть виконуватися паралельно та послідовно одночасно?
user87267867

2
Дочірні процеси не залежать від батьківського процесу. Вони мають власний простір пам’яті, PID та час виконання. Не впевнений, що ви маєте на увазі під послідовним, але так, вони працюватимуть паралельно і будуть заплановані окремо ОС для виконання.
Брайан

як викликати визначені користувачем функції як дочірній процес?
user87267867

Як я можу породити дочірній процес для виклику функції abc () {}
user87267867

2
Так, я не знав про цю бібліотеку, але, схоже, за коментарем Алекса Міллса ви можете виконати деякі роботи з потоками в Node. З огляду на це, наступне питання - чи слід вам? . . Вузол був розроблений від нульових до вільних програмістів від складності, що постачаються з потоками, але забезпечують подібну продуктивність для блокування вводу-виводу. Я відредагую свою відповідь, враховуючи той факт, що це можливо за допомогою посилання на бібліотеку.
Брайан

34

Існує також принаймні одна бібліотека для виконання власних потоків із Node.js: node-webworker-thread

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

Це в основному реалізує API браузера Web Worker для node.js.


3
це має бути правильно. відповідь, яка передбачає, що вузол може породжувати лише процеси, але не потоки, є неправильною.
Олександр Міллс

18

З Node 10.5 тепер існує підтримка багатопоточності , але вона є експериментальною . Сподіваюся, це незабаром стане стабільним.

Перевірка наступних ресурсів:


Оновлення :

Починаючи з Node 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 у завданнях, пов'язаних з процесором , з можливістю виконувати JavaScript у кількох ізоляторах V8 та обмінюватися даними між ними. Napa.js виставляється як модуль Node.js, хоча він також може бути вбудований у хост-процес без залежності від Node.js ".



3

Я потребував в реальну многопоточности в Node.js і що працювало для мене був нитка пакетом. Він породжує інший процес, який має власний цикл повідомлень Node.js, тому вони не блокують один одного. Налаштування просте, а документація швидко та швидко працює. Ваша основна програма та працівники можуть спілкуватися обома способами, і робочі "нитки" можуть бути вбиті, якщо це потрібно.

Оскільки багатопотоковість та Node.js є складною і широко обговорюваною темою, було досить важко знайти пакет, який відповідає моїм конкретним вимогам. На протокол це для мене не спрацювало :

  • tiny-worker дозволяв нерестувати робітників, але вони, здавалося, поділяли один і той же цикл повідомлень (але, можливо, я зробив щось не так - потоки мали більше документації, що дає мені впевненість, що він насправді використовував кілька процесів, тому я продовжував працювати, поки це не спрацювало)
  • Потоки webworker не дозволяли requireмодулів -ing у робочих, які мені потрібні

А для тих, хто запитує, навіщо мені потрібна справжня багатопоточність: Для програми, що включає Raspberry Pi та переривання. Один потік обробляє ці переривання, а інший піклується про збереження даних (і багато іншого).


1
Я ціную чудову думку, вкладену в цю відповідь!
MLissCetrus

3

Nodejs 10.5.0 реліз оголосив многопоточности в 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 із 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/… ?
serv-inc

Ні .. це не так ... Я все-таки повернув його назад у часі.
priyeshdkr



0

Можливо, ви шукали Promise.race (власне гоночне рішення вводу-виводу, а не потоки)

Якщо припустити, що ви (або інші, хто шукає це питання) хочуть перебігати нитки, щоб уникнути збою та уникнути витрат на операції вводу-виводу, це простий і природний спосіб це зробити (який не використовує потоки). Вузол розроблений для однопотокової роботи (шукайте цикл подій), тому уникайте використання потоків, якщо це можливо. Якщо моє припущення вірне, я рекомендую використовувати Promise.raceз setTimeout(приклад у посиланні). За допомогою цієї стратегії ви створили б список обіцянок, кожна з яких спробує якусь операцію вводу-виводу, і відхилила обіцянку, якщо є помилка (інакше час очікування). Promise.raceЗаява триває після першого дозволу / відмови, який , здається, що ви хочете. Сподіваюся, це комусь допомагає!


2
Це не має нічого спільного з нитками. Всі вони працюють в одному потоці.
Еван Керролл,

@EvanCarroll - Дякую, що попередив, що я недостатньо чіткий. Я попереджував це припущенням про те, чому хтось може шукати перегони потоків, і зазначив, що тут використовуються обіцянки у циклі подій Node. Виходячи з іншої мови, цілком можливо, що ви хочете виконати те, що роблять потоки, але ще не знайомі з циклом подій або обіцянками. Я хотів зазначити, що існують простіші способи досягнення цього, якщо це ваша мета. Я додав дужки, що тут не використовуються потоки. Повідомте мене, якщо це прояснить ситуацію.
смайлик

Здається, це також відповідає критеріям ОП: "Якщо якийсь метод не вдасться між усіма іншими потоками повинен бути вбитий", тож я вважав, що це було доречно.
смайлик

Promise.race виконує всі обіцянки послідовно, перемикаючись з одного на інший у випадку асинхронної операції (або чекаючи у випадку асинхронної функції).
Нагабхушан Бадді

0

Node.js не використовує потокову роботу. За словами його винахідника, це ключова особливість. На момент його винаходу нитки були повільними, проблематичними та складними. Node.js був створений в результаті розслідування ефективної одноядерної альтернативи. Більшість ентузіастів Node.js все ще цитують аргумент olde, ніби потоки не вдосконалювались за останні 50 років.

Як відомо, Node.js використовується для запуску JavaScript. Мова JavaScript також розвивалася протягом багатьох років. Тепер у нього є способи використання декількох ядер - тобто те, що роблять потоки. Отже, завдяки вдосконаленню JavaScript ви можете виконати кілька багатоядерних багатозадачних завдань у своїх додатках. user158 зазначає, що Node.js трохи з цим грає. Я нічого про це не знаю. Але навіщо чекати, поки Node.js схвалить пропозиції JavaScript.

Google для багатопоточності JavaScript замість багатопоточності Node.js. Ви дізнаєтесь про веб-працівників, обіцянки та інші речі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.