NodeJs è a thread singolo?
Node.js esegue il codice JavaScript in un singolo thread, il che significa che il tuo codice può eseguire solo un'attività alla volta. Ma Node.js stesso è multithread e fornisce thread nascosti attraverso la libreria `libuv`, che gestisce operazioni di I/O come la lettura di file da un disco o richieste di rete. Attraverso l'uso di thread nascosti, Node.js fornisce metodi asincroni che consentono al tuo codice di effettuare richieste di I/O senza bloccare il thread principale.
Node.js ci ha presentato il modulo worker-threads. Quel modulo consente di creare thread ed eseguire attività Javascript in parallelo. Se un thread termina un'attività, invia un messaggio al thread principale che contiene il risultato in modo che possiamo usarlo nel thread principale. I thread di lavoro non bloccano il thread principale, quindi possiamo dividere e distribuire il nostro compito a più par per ottimizzarlo.
Facciamone un esempio e guardiamolo più da vicino.
Stiamo creando un progetto Nodejs e installando il framework Express
mkdir multiple-thread
cd multiple-thread
npm init -y
npm install express
Prima di tutto, ci sono processi e thread. Dovremmo conoscere le differenze tra loro.
Che cos'è il processo?
Un processo sta eseguendo un programma nel sistema operativo. Può eseguire un compito alla volta.
Diamo un'occhiata più da vicino al processo più da vicino. Crea un file JS e registra il processo.
//ex-process.js
const processName = process.argv.slice(2)[0]
let count = 0;
while(true){
count++;
if(count === 3333 || count=== 6666){
console.log(`${processName}: ${count}`)
}
}
node ex-process.js FirstEx &
// & symbol means the Node program to run in the background, so we can use
our teminal for other works
Output
[1] 82942
FirstEx: 3333
FirstEx: 6666
ps |grep node
Output
82942 ttys001 2:38.85 node ex-process.js FirstEx
83105 ttys001 0:00.00 grep node
I thread sono un modo relativamente leggero per implementare più percorsi di esecuzione all'interno di un'applicazione. A livello di sistema, i programmi vengono eseguiti fianco a fianco, con il sistema che distribuisce il tempo di esecuzione a ciascun programma in base alle sue esigenze e alle esigenze di altri programmi.
Codifichiamo Express Server con il percorso non bloccante e i percorsi bloccanti
Codifichiamo un normale percorso di blocco per gli utenti. Dentro app.js;
const express = require('express');
const app = express();
app.get('/hello', (req,res)=>{
res.status(200).send(`Hello`);
})
app.get('/blocking-route', (req,res)=>{
console.log('Blocking route called')
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
})
app.listen(7333, ()=> console.log('Server started on port 7333'));
Non risponde finché non blocking-routeè finito e ha inviato una risposta.
Perché non ci ha risposto all'istante?
In questo esempio, il ciclo for associato alla CPU blocca il thread principale. Mentre il thread principale è bloccato, Node.js non può elaborare alcuna query finché il processo associato alla CPU non è terminato. quindi nessuno degli altri percorsi /hellofunziona come il /blocking-routepercorso viene caricato.
Pertanto, se disponiamo di un'API che ha migliaia di GETrichieste simultanee al percorso non bloccante come /hello, solo una richiesta al /blocking-routebloccherà tutti i percorsi nell'API. Ciò significa che rende tutti i percorsi dell'applicazione non rispondenti.
DAAA IT è javascript, non possiamo usare un altro thread
Amico Non è solo JS. È Nodejs. Possiamo scaricare un'attività legata alla CPU con thread di lavoro.
Prima di tutto, dovremmo controllare i nostri core con nprocil comando
nproc
output
8
Creiamo un altro file JS come worker.js, il nome dipende da te. In questo file, eseguiamo attività ad alta intensità di CPU
//worker.js
const { parentPort } = require("worker_threads");
let counter = 0;
console.log("Worker started");
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
parentPort.postMessage(counter);
//app.js
const express = require("express");
const { Worker } = require("worker_threads");
const app = express();
app.get("/blocking-route", async (req, res) => {
console.log("Blocking route called");
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
});
app.get("/hello", (req, res) => {
res.status(200).send(`Hello`);
});
app.get("/non-blocking-route", async (req, res) => {
console.log("Non-blocking route called");
const worker = new Worker("./worker.js");
worker.on("message", (data) => {
res.status(200).send(`result is ${data}`);
});
worker.on("error", (err) => {
res.status(404).send(` error ${err}`);
});
console.log("I am not blocked");
});
app.listen(7333, () => console.log("Server started on port 7333"));
Avviamo il server con node app.js. Apri il tuo browser e vai http://localhost:7333/non-blocking-routeprima che restituisca una risposta vai a http://localhost:7333/hello. Te ne sei reso conto? Riceviamo una risposta istantanea. Non c'è alcun blocco. Non abbiamo aspettato che gli altri percorsi finissero di caricarsi. Perché l'attività associata alla CPU viene scaricata e sta lavorando su un altro thread e il thread principale gestisce tutte le richieste. Possiamo utilizzare più lavoratori per migliorare le nostre prestazioni. Ad esempio, ho 8 core e posso dividere il mio processo in 8.
Conclusione
I lavoratori (thread) possono aiutare con le operazioni JavaScript a uso intensivo della CPU. A differenza di child_processo cluster, worker_threadspuò condividere la memoria.
In questo articolo, ho cercato di semplificare e spiegare come funziona worker_threads?
Grazie per aver letto

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































