
Na semana passada, o Node.js. versão 10.5.0 foi lançado, contendo uma inovação cuja importância é difícil de superestimar - suporte a multithreading na forma do módulo worker_threads . Imediatamente farei uma reserva.A API está em fase experimental e, portanto, pode mudar, mas agora você pode causar uma primeira impressão e ter uma idéia dos princípios e tecnologias estabelecidos em sua fundação. E se você desejar, participe da finalização da interface, escrevendo código ou corrigindo bugs (lista de problemas ).
História de aparência
Ao longo da vida do Node.js, a única maneira de paralelizar a computação era iniciar um novo processo, por exemplo, usando o módulo de cluster. Por muitas razões, essa abordagem não se adequa aos desenvolvedores, principalmente porque leva a um carregamento repetido do código executável do Node.js. com todos os módulos internos na memória do computador, o que é uma maneira ineficiente de gastar recursos.
No entanto, a discussão sobre a implementação do multithreading no Node.js. sempre se baseou na complexidade da V8 e em um grande número de incógnitas: como conectar módulos nativos, compartilhar memória, comunicar-se entre threads e muito mais. E enquanto os desenvolvedores procuravam qual lado abordar o tópico na Web, a API Worker foi implementada com sucesso, o que se tornou uma diretriz nos estágios iniciais. O desenvolvimento começou com addaleax e foi assumido pela comunidade.
O trabalho ativo foi realizado durante o ano, durante o qual os requisitos de design foram especificados e a API adquiriu seus próprios recursos específicos do Node.js. O módulo em si foi chamado worker_threads. Abaixo, descreverei brevemente o worker_threads em termos gerais e, para um estudo detalhado, recomendo que você visite a página de documentação oficial .
Descrição do produto
Como mencionado acima, o objetivo desse desenvolvimento é melhorar a produtividade, distribuindo a carga em threads separados no mesmo processo, em vez de iniciar vários processos. Portanto, os threads suportam a conexão de todos os módulos disponíveis para o processo principal (atualmente, os módulos nativos não são suportados).
Como na API Worker, a interação entre o fluxo principal e o filho é realizada através da transferência de objetos Transferrable via postMessage, o que evita os problemas de acesso simultâneo, embora exija acesso adicional à memória para copiar dados. Nesse caso, objetos como SharedArrayBuffer mantêm seu comportamento e não causam realocação.
O MessageChannel e o MessagePort foram retirados da WebAPI , que permite criar canais de mensagens isolados e transferi-los entre threads.
Para tentar worker_threads em ação, ao iniciar o processo, você deve especificar um sinalizador especial:
node --experimental-worker main.js
Exemplo
Como a API ainda pode mudar, não a descreverei, mas darei um exemplo de troca de mensagens entre os threads pai e filho, na qual o thread filho relata seu threadId por meio do MessagePort e sai.
Fluxo principal
Código de exemplo para o encadeamento principal:
Fluxo filho
O encadeamento filho permanece até que seu loop de eventos esteja vazio. Portanto, imediatamente após a worker.js
do código do worker.js
encadeamento será fechado automaticamente. Para se comunicar com o pai, parentPort é usado:
No encadeamento filho, o objeto do processo é substituído e seu comportamento é ligeiramente diferente do comportamento do processo no encadeamento pai. Em particular, não há como responder aos sinais SIGNINT, alterar os valores de process.env
e chamar process.exit
para apenas o trabalho, mas não o processo inteiro.
Conclusão
Os trabalhadores simplificarão bastante a criação de aplicativos que exigem interação entre seções de código executável paralelo e, o que é especialmente importante, tornam a comunicação e o controle de fluxo da maneira mais óbvia. E também permitirá evitar restrições específicas da plataforma causadas pela diferença entre Windows e Unix. Estou certo de que as oportunidades que abrirão atrairão novos desenvolvedores que ainda não optaram pelo Node.js. Enquanto isso, continue monitorando as alterações e se conectando ao processo de desenvolvimento da API no repositório .
Referências