Como criar threads em nodejs

91

Existe alguma maneira de criar threads para executar vários métodos ao mesmo tempo?

Dessa forma, se algum método falhar entre todos os outros threads, ele deve ser eliminado.

user87267867
fonte

Respostas:

94

Cada processo node.js tem um único encadeamento por design. Portanto, para obter vários threads, você precisa ter vários processos (como alguns outros pôsteres apontaram, também existem bibliotecas para as quais você pode se vincular que lhe darão a capacidade de trabalhar com threads no Node, mas esse recurso não existe sem essas bibliotecas . Veja a resposta de Shawn Vincent referenciando https://github.com/audreyt/node-webworker-threads )

Você pode iniciar processos filho a partir do seu processo principal, conforme mostrado aqui na documentação do node.js: http://nodejs.org/api/child_process.html . Os exemplos são muito bons nesta página e são bastante diretos.

Seu processo pai pode então observar o evento de fechamento em qualquer processo iniciado e, então, pode forçar o fechamento dos outros processos que você iniciou para atingir o tipo de estratégia de falha em todas as paradas de que você está falando.

Veja também: Node.js em máquinas multi-core

Brian
fonte
processos podem ser executados paralelos e sequenciais ao mesmo tempo?
user87267867
2
Os processos filho são independentes do processo pai. Eles têm seu próprio espaço de memória, PID e tempo de execução. Não tenho certeza do que você quer dizer com sequencial, mas sim, eles serão executados em paralelo e agendados separadamente pelo SO para execução.
Brian,
como chamar funções definidas pelo usuário como processo filho?
user87267867
Como posso gerar um processo filho para chamar a função abc () {}
user87267867
2
Huh, não estava ciente dessa biblioteca, mas parece que, de acordo com o comentário de Alex Mills, você pode fazer algum trabalho de threading no Node. Dito isso, a próxima pergunta é você. . . O Node foi projetado do zero para liberar os programadores da complexidade que vem com threads, mas produz desempenho de tipo semelhante para bloquear E / S. Vou editar minha resposta para explicar o fato de que é possível usar a biblioteca referenciada.
Brian
34

Há também pelo menos uma biblioteca para fazer threading nativo de dentro do Node.js: node-webworker-threads

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

Isso basicamente implementa a API do navegador Web Worker para node.js.

Shawn Vincent
fonte
3
isso deve estar correto. a resposta sugerindo que o nó só pode gerar processos, mas não threads, está errada.
Alexander Mills
9

Você pode obter multi-threading usando Napa.js.

https://github.com/Microsoft/napajs

"Napa.js é um tempo de execução JavaScript multi-threaded baseado em V8, que foi originalmente projetado para desenvolver serviços altamente iterativos com desempenho não comprometido no Bing. Conforme ele evolui, achamos útil complementar o Node.js em tarefas vinculadas à CPU , com a capacidade de executar JavaScript em vários isolados V8 e se comunicar entre eles. O Napa.js é exposto como um módulo Node.js, enquanto também pode ser incorporado em um processo host sem dependência do Node.js. "

shmuli
fonte
4

Se você estiver usando Rx, é bastante simples conectar-se ao rxjs-cluster para dividir o trabalho em execução paralela. (isenção de responsabilidade: eu sou o autor)

https://www.npmjs.com/package/rxjs-cluster

Jonathan Dunlap
fonte
3

Eu precisava de multithreading real em Node.js e o que funcionou para mim foi o pacote de threads . Ele gera outro processo com seu próprio loop de mensagem Node.js, para que eles não bloqueiem um ao outro. A configuração é fácil e a documentação permite que você comece a trabalhar rapidamente. Seu programa principal e os trabalhadores podem se comunicar de ambas as maneiras e "threads" de trabalho podem ser eliminados, se necessário.

Já que multithreading e Node.js são um tópico complicado e amplamente discutido, foi muito difícil encontrar um pacote que funcionasse para meu requisito específico. Para que conste , não funcionou para mim :

  • tiny-worker permitiu a spawning de workers, mas eles pareciam compartilhar o mesmo loop de mensagem (mas pode ser que eu fiz algo errado - os threads tinham mais documentação me dando confiança de que realmente usavam vários processos, então continuei até que funcionou)
  • webworker-threads não permitiam requiremódulos -ing em workers que eu precisava

E para aqueles que estão perguntando por que eu precisava de multi-threading real : Para um aplicativo envolvendo o Raspberry Pi e interrupções. Um thread está lidando com essas interrupções e outro cuida de armazenar os dados (e mais).

Heinrich Ulbricht
fonte
1
Agradeço o grande pensamento colocado nesta resposta!
MLissCetrus
3

O nodejs 10.5.0 liberação anunciou multithreading em Node.js . O recurso ainda é experimental. Há um novo módulo worker_threads disponível agora.

Você pode começar a usar threads de trabalho se executar o Node.js v10.5.0 ou superior , mas esta é uma API experimental . Não está disponível por padrão: você precisa habilitá-lo usando  --experimental-worker ao invocar o Node.js.

Aqui está um exemplo com ES6 e worker_threads habilitados, testado na versão 12.3.1

//package.json

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

Agora, você precisa importar o Worker de worker_threads . Nota: Você precisa declarar seus arquivos js com extensão '.mjs' para suporte 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();

Finalmente, criamos um 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}`);

Resultado:

npm run start

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5
Priyeshdkr
fonte
2
Este é o seu artigo: blog.logrocket.com/… ?
serv-inc
Não ... não é ... eu me referi no tempo.
priyeshdkr
2

O NodeJS agora inclui tópicos (como um recurso experimental no momento da resposta).

James Holmes
fonte
0

Você pode estar procurando Promise.race(solução de corrida de E / S nativa, não threads)

Supondo que você (ou outras pessoas que estão pesquisando esta questão) queiram disputar threads para evitar falhas e evitar o custo das operações de E / S, essa é uma maneira simples e nativa de fazer isso (que não usa threads). O nó é projetado para ter um único thread (consulte o loop de eventos), portanto, evite usar threads, se possível. Se minha suposição estiver correta, recomendo que você use Promise.racecom setTimeout(exemplo no link). Com essa estratégia, você executaria uma lista de promessas em que cada uma tentaria alguma operação de E / S e rejeitaria a promessa se houvesse um erro (caso contrário, tempo limite). A Promise.raceafirmação continua após a primeira resolução / rejeição, que parece ser o que você deseja. Espero que isso ajude alguém!

smileham
fonte
2
Isso não tem nada a ver com tópicos. Todos eles correm no mesmo segmento.
Evan Carroll
@EvanCarroll - Obrigado por me alertar que não fui suficientemente claro. Comecei com uma suposição sobre por que alguém pode estar procurando thread racing e observei que isso usa promessas no loop de eventos do Node. Vindo de outra linguagem, é bem possível que você queira realizar o que os threads fazem, mas ainda não esteja familiarizado com o loop de eventos ou promessas. Gostaria de observar que existem maneiras mais simples de fazer isso se esse for o seu objetivo. Eu adicionei um parênteses que isso não usa tópicos. Deixe-me saber se isso esclarecer as coisas.
smileham
Ele também parece responder aos critérios dos OPs: "Se algum método falhar entre todos os outros threads, deve ser eliminado", então achei que era relevante.
smileham
Promise.race executa todas as promessas sequencialmente, mudando de uma para outra no caso de uma operação assíncrona (ou de espera no caso de uma função assíncrona).
Nagabhushan Baddi
0

Node.js não usa threading. Segundo seu inventor, essa é uma característica fundamental. Na época de sua invenção, os fios eram lentos, problemáticos e difíceis. O Node.js foi criado como resultado de uma investigação sobre uma alternativa eficiente de núcleo único. A maioria dos entusiastas do Node.js ainda cita seus velhos argumentos, como se os threads não tivessem sido aprimorados nos últimos 50 anos.

Como você sabe, o Node.js é usado para executar JavaScript. A linguagem JavaScript também se desenvolveu ao longo dos anos. Agora ele tem maneiras de usar vários núcleos - ou seja, o que os Threads fazem. Portanto, por meio de avanços em JavaScript, você pode fazer algumas multitarefas multi-core em seus aplicativos. user158 aponta que Node.js está brincando um pouco com ele. Eu não sei nada sobre isso. Mas por que esperar que o Node.js aprove o que o JavaScript tem a oferecer.

Multi-threading do Google para JavaScript em vez de multi-threading Node.js. Você descobrirá sobre Web Workers, Promises e outras coisas.

Roger F. Gay
fonte