Cara membuat utas di nodejs

91

Apakah ada cara untuk membuat utas untuk menjalankan beberapa metode sekaligus?

Dengan begitu, jika ada metode yang gagal di antara semua utas lainnya harus dimatikan.

pengguna87267867
sumber

Jawaban:

94

Setiap proses node.js adalah single threaded by design. Oleh karena itu untuk mendapatkan banyak utas, Anda harus memiliki banyak proses (Seperti yang ditunjukkan oleh beberapa poster lain, ada juga pustaka yang dapat Anda tautkan yang akan memberi Anda kemampuan untuk bekerja dengan utas di Node, tetapi tidak ada kemampuan seperti itu tanpa pustaka tersebut. . Lihat jawaban oleh Shawn Vincent merujuk https://github.com/audreyt/node-webworker-threads )

Anda dapat memulai proses anak dari proses utama Anda seperti yang ditunjukkan di sini dalam dokumentasi node.js: http://nodejs.org/api/child_process.html . Contohnya cukup bagus di halaman ini dan cukup mudah.

Proses induk Anda kemudian dapat melihat penutupan acara pada setiap proses yang dimulai dan kemudian dapat memaksa menutup proses lain yang Anda mulai untuk mencapai jenis satu gagal semua strategi berhenti yang Anda bicarakan.

Lihat juga: Node.js pada mesin multi-inti

Brian
sumber
proses dapat berjalan paralel dan berurutan pada suatu waktu?
pengguna87267867
2
Proses anak tidak bergantung pada proses induk. Mereka memiliki ruang memori, PID, dan waktu eksekusi sendiri. Tidak yakin apa yang Anda maksud dengan berurutan, tapi ya, mereka akan berjalan secara paralel dan dijadwalkan secara terpisah oleh OS untuk dieksekusi.
Brian
bagaimana memanggil fungsi yang ditentukan pengguna sebagai proses anak?
pengguna87267867
Bagaimana saya bisa menelurkan proses anak untuk memanggil fungsi abc () {}
user87267867
2
Huh, tidak mengetahui library itu tetapi sepertinya menurut komentar Alex Mills Anda dapat melakukan beberapa pekerjaan threading di Node. Karena itu, pertanyaan selanjutnya adalah haruskah Anda. . . Node dirancang dari awal hingga pemrogram bebas dari kompleksitas yang dilengkapi dengan utas tetapi menghasilkan kinerja jenis yang serupa untuk memblokir I / O. Saya akan mengedit jawaban saya ke akun untuk fakta bahwa itu mungkin menggunakan perpustakaan yang direferensikan.
Brian
34

Ada juga setidaknya satu library untuk melakukan penguliran asli dari dalam Node.js: node-webworker-threads

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

Ini pada dasarnya mengimplementasikan API browser Web Worker untuk node.js.

Shawn Vincent
sumber
3
ini seharusnya benar. jawaban yang menunjukkan bahwa node hanya dapat menelurkan proses, tetapi bukan utas, adalah salah.
Alexander Mills
9

Anda bisa mendapatkan multi-threading menggunakan Napa.js.

https://github.com/Microsoft/napajs

"Napa.js adalah runtime JavaScript multi-utas yang dibangun pada V8, yang pada awalnya dirancang untuk mengembangkan layanan yang sangat berulang dengan kinerja yang tidak terganggu di Bing. Seiring perkembangannya, kami merasa berguna untuk melengkapi Node.js dalam tugas yang terikat dengan CPU , dengan kemampuan mengeksekusi JavaScript di beberapa isolasi V8 dan berkomunikasi di antara keduanya. Napa.js diekspos sebagai modul Node.js, sementara itu juga dapat disematkan dalam proses host tanpa ketergantungan Node.js. "

shmuli
sumber
3

Saya membutuhkan multithreading nyata di Node.js dan yang berhasil untuk saya adalah paket utasnya . Ini memunculkan proses lain yang memiliki loop pesan Node.js sendiri, jadi mereka tidak saling memblokir. Penyiapannya mudah dan dokumentasinya membuat Anda siap dan berfungsi dengan cepat. Program utama Anda dan pekerja dapat berkomunikasi dengan dua cara dan "utas" pekerja dapat dimatikan jika diperlukan.

Karena multithreading dan Node.js adalah topik yang rumit dan banyak dibahas, cukup sulit untuk menemukan paket yang sesuai dengan kebutuhan spesifik saya . Sebagai catatan, ini tidak berhasil untuk saya :

  • pekerja kecil mengizinkan pekerja pemijahan, tetapi mereka tampaknya berbagi loop pesan yang sama (tetapi mungkin saya melakukan sesuatu yang salah - utas memiliki lebih banyak dokumentasi yang memberi saya kepercayaan diri itu benar - benar menggunakan banyak proses, jadi saya terus melakukannya sampai berhasil)
  • webworker-threads tidak mengizinkan require-ing modul pada pekerja yang saya butuhkan

Dan bagi mereka yang bertanya mengapa saya membutuhkan multi-threading nyata : Untuk aplikasi yang melibatkan Raspberry Pi dan interupsi. Satu utas menangani interupsi tersebut dan utas lainnya menangani penyimpanan data (dan lainnya).

Heinrich Ulbricht
sumber
1
Saya menghargai pemikiran luar biasa yang dimasukkan ke dalam jawaban ini!
MLissCetrus
3

The nodejs 10.5.0 rilis telah mengumumkan multithreading di Node.js . Fiturnya masih eksperimental. Ada modul worker_threads baru yang tersedia sekarang.

Anda dapat mulai menggunakan thread pekerja jika Anda menjalankan Node.js v10.5.0 atau lebih tinggi , tetapi ini adalah API eksperimental . Ini tidak tersedia secara default: Anda harus mengaktifkannya dengan menggunakan  --experimental-worker saat menjalankan Node.js.

Berikut adalah contoh dengan ES6 dan worker_threads diaktifkan, diuji pada versi 12.3.1

//package.json

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

Sekarang, Anda perlu mengimpor Worker dari worker_threads . Catatan: Anda perlu mendeklarasikan file js Anda dengan ekstensi '.mjs' untuk dukungan 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();

Terakhir, kami membuat 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}`);

Keluaran:

npm jalankan mulai

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5
priyeshdkr
sumber
2
Apakah ini artikel Anda: blog.logrocket.com/… ?
serv-inc
Tidak..bukan ... Aku memang merujuknya ke masa lalu.
priyeshdkr
2

NodeJS sekarang menyertakan utas (sebagai fitur eksperimental pada saat menjawab).

James Holmes
sumber
0

Anda mungkin mencari Promise.race(solusi balapan I / O asli, bukan utas)

Dengan asumsi Anda (atau orang lain yang menelusuri pertanyaan ini) ingin balapan untaian untuk menghindari kegagalan dan menghindari biaya operasi I / O, ini adalah cara sederhana dan asli untuk menyelesaikannya (yang tidak menggunakan utas). Node dirancang untuk menjadi single thread (cari event loop), jadi hindari menggunakan thread jika memungkinkan. Jika asumsi saya benar, saya sarankan Anda menggunakan Promise.racedengan setTimeout(contoh di tautan). Dengan strategi ini, Anda akan berlomba dengan daftar janji yang masing-masing mencoba beberapa operasi I / O dan menolak janji jika ada kesalahan (jika tidak, batas waktu). The Promise.racepernyataan berlanjut setelah yang pertama resolusi / penolakan, yang tampaknya menjadi apa yang Anda inginkan. Semoga ini bisa membantu seseorang!

smileham
sumber
2
Ini tidak ada hubungannya dengan utas. Semuanya berjalan di utas yang sama.
Evan Carroll
@EvanCarroll - Terima kasih telah memberi tahu saya bahwa saya tidak cukup jelas. Saya memulainya dengan asumsi tentang mengapa seseorang mungkin mencari balapan thread dan mencatat bahwa ini menggunakan promise dalam loop acara Node. Berasal dari bahasa lain, sangat mungkin Anda ingin menyelesaikan apa yang dilakukan thread tetapi belum terbiasa dengan loop atau promise acara. Saya ingin mencatat bahwa ada cara yang lebih sederhana untuk mencapainya jika itu adalah tujuan Anda. Saya menambahkan tanda kurung bahwa ini tidak menggunakan utas. Beri tahu saya jika ini menyelesaikan masalah.
smileham
Tampaknya juga untuk menjawab kriteria OP: "Jika ada metode yang gagal di antara semua utas lainnya harus dimatikan", jadi saya pikir itu relevan.
smileham
Promise.race mengeksekusi semua promise secara berurutan, beralih dari satu janji ke yang lain jika ada operasi asinkron (atau menunggu jika ada fungsi asinkron).
Nagabhushan Baddi
0

Node.js tidak menggunakan threading. Menurut penemunya, itulah ciri utama. Pada saat penemuannya, utasnya lambat, bermasalah, dan sulit. Node.js dibuat sebagai hasil investigasi terhadap alternatif inti tunggal yang efisien. Sebagian besar penggemar Node.js masih mengutip argumen Anda seolah-olah utas belum diperbaiki selama 50 tahun terakhir.

Seperti yang Anda ketahui, Node.js digunakan untuk menjalankan JavaScript. Bahasa JavaScript juga telah berkembang selama bertahun-tahun. Sekarang ada cara untuk menggunakan banyak inti - yaitu apa yang dilakukan Thread. Jadi, melalui kemajuan dalam JavaScript, Anda dapat melakukan beberapa multi-core multi-tasking dalam aplikasi Anda. user158 menunjukkan bahwa Node.js sedikit bermain dengannya. Saya tidak tahu apa-apa tentang itu. Tapi mengapa menunggu Node.js untuk menyetujui apa yang ditawarkan JavaScript.

Google untuk multi-threading JavaScript, bukan multi-threading Node.js. Anda akan mengetahui tentang Pekerja Web, Janji, dan hal-hal lain.

Roger F. Gay
sumber