Worker Threads Là Gì? Bạn đã Biết Khi Nào Thì Sử Dụng ... - v

HomeTrang chủPostsPostsThreadsThreadsSearchTìm kiếmNotificationThông báoĐăng nhập
  • 🇻🇳Tiếng Việt
  • 💡Chế độ
  • 👋Đăng xuất
  • 💎Nâng cấp
  • 👤Đăng nhập
  • 🇻🇳Tiếng Việt
  • 💡Chế độ

🎉Tính năng mới

Khám phá bài viết hàng tuần dành cho bạn bằng cách bấm vào đây.

Đã hiểu 👌Worker threads là gì? Bạn đã biết khi nào thì sử dụng Worker threads trong node.js chưa?Worker threads là gì? Bạn đã biết khi nào thì sử dụng Worker threads trong node.js chưa?Tin ngắn hàng ngày dành cho bạn
  • Cuối ngày rồi vẫn có "drama" cho mọi người hóng đây. Mattermost - ứng dụng nhắn tin mã nguồn mở tương tự như Slack đang thu hút sự chú ý của cộng đồng mạng khi đặt ra giới hạn 10.000 tin nhắn cho mỗi kênh trao đổi, điều đó đồng nghĩa nếu kênh có số lượng tin nhắn nhiều hơn thì sẽ không xem lại hoặc tìm kiếm được nữa.

    Sỡ dĩ mọi người gay gắt như vậy là vì từ đầu Mattermost đi theo hướng nguồn mở hoàn toàn, còn giờ đây họ đang thắt chặt giới hạn để hướng tới việc bán sản phẩm hơn. Nếu như bạn còn nhớ thì cách đây không lâu MinIO cũng gặp phải trường hợp tương tự. Phần nguồn mở không được coi trọng nữa, thậm chí còn bị cắt bớt, trong khi phiên bản thương mại được đẩy mạnh. Các sự việc này khiến cho cộng đồng mã nguồn mở rất thất vọng.

    Hôm nay mới phát hành phiên bản mới cho ứng dụng ghi chú OpenNotas, mã nguồn mở hoàn toàn, vẫn duy trì đều đặn, chưa kịp nghĩ đến phiên bản trả phí mà đọc mấy tin này lại kiểu: thôi thì đợi lúc nào sản phẩm ngon thì hãy bán 😆

    Mattermost restricted access to old messages after 10000 limit is reached

    » Xem thêm
  • Mới biết đến công cụ tạo CV từ tệp yaml nè mọi người: rendercv/rendercv

    Thay vì đi tìm công cụ, đau đầu chọn giao diện, trình bày bố cục, thì bây giờ chỉ cần viết CV như tạo một tệp cấu hình, chạy một lệnh là có ngay một bản CV hoàn chỉnh 😆

    » Xem thêm
  • Anthropic tiếp tục giới thiệu Claude works in your browser - là một tiện ích mở rộng trong trình duyệt Google Chrome. Như vậy Claude giờ đây có thể điều hướng, nhấp vào các nút và điền vào biểu mẫu ngay trên trình duyệt, giúp hoàn thành một số tác vụ đơn giản bằng cách ra lệnh.

    Đang trong giai đoạn thử nghiệm cho nên vẫn còn lỗi và chậm, với cả người dùng miễn phí vẫn chưa được trải nghiệm 😅

    » Xem thêm

Vấn đề

Worker threads được giới thiệu lần đầu tiên từ phiên bản Node.js 10.5, tại thời điểm đó API của nó vẫn đang còn trong giai đoạn thử nghiệm trước khi chính thức nhận được bản phát hành ổn định ở phiên bản 12LTS.

Worker threads cung cấp một giải pháp giúp chạy mã Javascript trên một luồng khác song song với luồng chính. Vậy cụ thể điều này là như thế nào và nó mang lại lợi ích gì thì xin mời các bạn đọc tiếp bài viết dưới đây.

Các tác vụ đòi hỏi nhiều CPU

Có thể bạn đã biết node.js xử lý các tác vụ I/O không đồng bộ rất tốt. Nói đến I/O ở đây người ta thường liên tưởng đến những công việc liên quan đến đọc/ghi dữ liệu vào file, hay các request http...

Còn với những công việc đồng bộ chẳng hạn như những phép tính phức tạp trong một tập dữ liệu rất lớn, điều đó sẽ gây ra một cuộc tắc nghẽn nghiêm trọng ở trong luồng chính.

Tưởng tượng nếu một phép tính đồng bộ mất 10 giây để xử lý, điều đó có nghĩa là luồng chính sẽ bị chặn trong 10 giây để xử lý yêu cầu đó trước khi nó có thể xử lý những yêu cầu tiếp theo và điều đó thật là tai hại bởi vì không một ai muốn một tốc độ phản hồi của máy chủ như vậy cả.

Một ví dụ kinh điển cho những phép tính như vậy là dãy Fibonacci. Theo định nghĩa Fibonacci là một dãy vô hạn các số tự nhiên bắt đầu bằng 0 và 1, các phần tử sau đó được thiết lập theo quy tắc mỗi phần tử luôn bằng tổng hai phần tử trước nó. Một hàm Fibonacci trong Javascript có thể được viết như sau:

const fibonacci = (n) => { var i; var fib = []; fib[0] = 0; fib[1] = 1; for (i = 2; i <= n; i++) { fib[i] = fib[i - 2] + fib[i - 1]; } return fib; }

Sau đó hãy thử gọi hàm fibonacci(999999), luồng chính của bạn có thể sẽ mất hơn một giây để tính toán kết quả đó.

Woker threads là gì?

Worker threads là một module trong node.js cho phép chạy mã Javascript song song với luồng chính. Mỗi worker được chạy độc lập với nhau, tuy nhiên chúng có thể giao tiếp với nhau thông qua postMessage(). Để tìm hiểu kỹ hơn, các bạn có thể xem tài liệu đầy đủ về Worker threads ở Worker threads.

Tại sao lại cần Worker threads?

Như đã trình bày ở đầu bài viết, chúng ta có thể cần đến Worker threads để xử lý những trường hợp tính toán dữ liệu lớn hoặc phức tạp để tránh việc chặn luồng chính.

Luồng chính sẽ gửi yêu cầu đến một worker yêu cầu nó thực hiện các mã Javascript. Sau khi hoàn thành, worker sẽ thông báo đến cho luồng chính biết bằng cách gọi hàm postMessage(). Luồng chính nhận dữ liệu từ worker rồi tiếp tục xử lý yêu cầu đó.

Chúng ta có thể thấy vì mã Javascript xử lý dữ liệu phức tạp không chạy ở trong luồng chính nữa cho nên các yêu cầu tiếp theo vẫn được xử lý như bình thường mà hoàn toàn không bị chặn.

Chi phí (cost) tạo một worker

Cho những ai chưa biết trước khi có Worker threads từ version 10.15, chúng ta đã có một số cách triển khai khác để chạy mã Javascript trên một luồng khác đó là Cluster và Child Process.

Cluster tận dụng tối đa số luồng của CPU để triển khai tối đa số luồng chính vì mặc định khi triển khai một dự án node.js nó chỉ chạy trên một luồng. Bằng cách dùng Cluster nếu máy chủ của chúng ta có 4 nhân 8 luồng thì số luồng chính tối đa được tạo ra là 8 - bằng với số luồng của CPU. Lúc này các yêu cầu đến sẽ được phân chia luân phiên nhau theo một giải thuật nào đó ví dụ như round-robin...Nhìn chúng, Cluster là một giải pháp tận dụng số luồng của CPU để thêm một số lượng luồng chính khác.

Child Process là một giải pháp khác với Cluster. Bằng cách tạo ra một process riêng biệt với triển khai đầy đủ của một event loop + một main thread cho nên điều này gây ra một yêu cầu tài nguyên lớn cho mỗi process được tạo ra. Mặt khác, vì mỗi process là độc lập về bộ nhớ cho nên việc giao tiếp giữa các process tương đối phức tạp.

Worker threads được sinh ra để giải quyết bài toán về chi phí tài nguyên sử dụng của Child Process. Thay vì tạo một process mới, worker threads tạo ra một thread mới trong chính process của ứng dụng đang chạy. Điều này giúp giảm thiểu tài nguyên, vì tài nguyên để tạo một thread là nhỏ hơn so với process. Mặc khác các thread có tài nguyên sử dụng chung nên việc giao tiếp giữa chúng tương đối dễ dàng.

Để dễ hình dung, bạn có thể tham khảo sơ đồ so sánh về Child Process và Worker threads:

Sơ đồ worker threads

Tuy nhiên, cả hai cách triển khai Child Process và Worker threads đều tốn kém về mặt tài nguyên của hệ thống vì thế hãy cân nhắc việc tạo ra quá nhiều chúng khi sử dụng.

Sử dụng Worker threads như thế nào?

Tài liệu của node.js có đề cập đến cách triển khai đơn giản một worker, các bạn có thể xem tại Worker threads.

Trong bài viết này tôi sẽ lấy ví dụ cách triển khai đơn giản một worker thực hiện việc tính toán fibonacci trong một thread khác.

Đầu tiên hãy tạo một file main.js:

const { Worker } = require('worker_threads'); const runService = (workerData) => { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`stopped with ${code} exit code`)); }); }) } const run = async () => { const result = await runService(999999); console.log(result); } run().catch(console.log);

Tiếp theo tạo file worker.js:

const { parentPort, workerData } = require('worker_threads'); const fibonacci = (n) => { var i; var fib = []; fib[0] = 0; fib[1] = 1; for (i = 2; i <= n; i++) { fib[i] = fib[i - 2] + fib[i - 1]; } parentPort.postMessage(fib); } fibonacci(workerData);

Sau đó hãy chạy thử main.js bạn sẽ thấy kết quả của dãy Fibonacci trong giây lát.

Để giải thích đoạn mã này, khi trong main gọi một new Worker nó sẽ tạo ra một worker là những mã có trong file worker.js. new Worker nhận vào tham số thứ hai là workerData để truyền dữ liệu từ main sang worker. Worker sau khi xử lý xong sẽ gọi một hàm postMessage để báo lại với main kết quả.

Trong triển khai Worker threads thực tế, chúng ta nên tuân thủ theo một nguyên tắc được mọi người đồng thuận để tạo sự thống nhất. Một trong số đó có thể kể đến như sử dụng những package được cộng đồng xây dựng sẵn với độ tương thích cao cùng khả năng triển khai nhanh chóng như node-worker-threads-pool npm.

Ví dụ để triển khai lại đoạn mã Fibonacci trên bằng package, tôi sẽ rút ngắn được mã đồng thời mã cũng trở nên ngắn gọn và dễ đọc hơn:

const { StaticPool } = require('node-worker-threads-pool'); const fibonacci = (n) => { var i; var fib = []; fib[0] = 0; fib[1] = 1; for (i = 2; i <= n; i++) { fib[i] = fib[i - 2] + fib[i - 1]; } return fib; } const staticPool = new StaticPool({ size: 4, task: fibonacci, }); staticPool.exec(999999).then(console.log);

Tổng kết

Worker threads là một module trong node.js cho phép chạy mã Javascript song song với luồng chính. Sử dụng worker threads khi chúng ta có những đoạn mã đồng bộ chiếm một thời gian xử lý lớn. Bằng cách đó sẽ giảm tải được cho luồng chính tiếp tục xử lý những yêu cầu tiếp theo mà không bị chặn trong một khoảng thời gian.

Chi phí tài nguyên để tạo ra một worker là ít hơn so với Child Process, tuy nhiên cả hai vốn đều "đắt giá" nên cần thận trọng khi tạo ra quá nhiều.

Triển khai woker threads cũng trở nên dễ dàng với sự trợ giúp của các package được cộng đồng hỗ trợ trên npm ví dụ như package node-worker-threads-pool npm có sẵn trên npm.

Cao cấpHello

5 bài học sâu sắc

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!

Tìm hiểu ngayXem tất cảsvg5 bài học sâu sắc

Kevin Systrom - đồng sáng lập Instargram đã phát triển ứng dụng Instagram từ một ý tưởng cá nhân về chia sẻ hình ảnh đẹp. Chỉ sau 2 năm, Instagram được Facebook mua lại với giá 1 tỷ USD. Elon Musk học lập trình từ năm 10 tuổi, lập trình và bán trò chơi điện tử đầu tiên với giá 500$ khi mới 12 tuổi. Điểm chung của họ là có niềm đam mê tự học lập trình, và đều bắt đầu từ những dự án cá nhân của mình. Ngoài kia, còn rất nhiều câu chuyện về sự thành công của nhiều người khác. Tất nhiên! Họ phải bắt đầu từ đâu đó.

Tại 2coffee.dev, chúng tôi biết rằng không thể so sánh với những tên tuổi lớn. Chúng tôi đơn giản bắt đầu từ niềm đam mê công nghệ cùng với những con chữ, với hy vọng truyền đạt được thông điệp và bài học đến với mọi người. Trải qua chặng đường 5 năm phát triển, chúng tôi đã đạt được thành công nhất định, đáng chú ý nhất là những bài học.

Trong bài viết này, chúng tôi sẽ điểm lại 5 bài học sâu sắc, đúc kết từ quá trình làm một Blogger. Hãy trở thành hội viên để nghe câu chuyện ngay hôm nay!

Đăng ký hội viên ngay ** Gói hội viên chưa có sẵn. Vui lòng quay lại sau.Tôi hiểu rồi

Đăng ký nhận thông báo bài viết mới

Hãy cho phép gửi thông báohoặchoặcGửi* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (6)

Nội dung bình luận...Bình luậnẨn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarẨn danh2 năm trước

Thư viện node-worker-threads-pool này chỉ giúp function chạy trên luồng riêng chứ không chạy trên multi CPU cùng lúc.

Trả lờiBình luậnAvatarẨn danh2 năm trước

Thư viện node-worker-threads-pool này chỉ giúp function chạy trên luồng riêng chứ không chạy trên multi CPU cùng lúc.

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarĐình Trung2 năm trước

worker threads có giống/khác gì với worker pools không a?

Trả lờiBình luậnAvatarĐình Trung2 năm trước

worker threads có giống/khác gì với worker pools không a?

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarXuân Hoài Tống2 năm trước

Khác bạn ạ, mình có series bài viết nói về kiến trúc Node.js bạn có thể tìm đọc lại sẽ dễ hiểu hơn.

AvatarTrần Huy Hoàng2 năm trước

Ngoài tính dãy fibo trên kia ra thì có ứng dụng thực tế nào nữa ko bạn?

Trả lờiBình luậnAvatarTrần Huy Hoàng2 năm trước

Ngoài tính dãy fibo trên kia ra thì có ứng dụng thực tế nào nữa ko bạn?

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarXuân Hoài Tống2 năm trước

Một câu hỏi khó, bạn có thể áp dụng trong bất kì trường hợp nào mà "công việc" của bạn đủ lâu để chặn luồng chính, ví dụ như xử lý hình ảnh, video chẳng hạn.

AvatarTiến Đức3 năm trước

nếu vậy thì khi nào dùng worker threads khi nào dùng child process vậy ạ

Trả lờiBình luậnAvatarTiến Đức3 năm trước

nếu vậy thì khi nào dùng worker threads khi nào dùng child process vậy ạ

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarXuân Hoài Tống3 năm trước

Câu hỏi này chắc có thời gian mình sẽ viết một bài riêng, nhưng để mà nói ngắn gọn là worker threads được yêu thích sử dụng hơn

AvatarNguyễn Minh Phương2 năm trước

theo ngu kiến của e thì khi nào bác cần scale up project của bác mà ko muốn dùng đến các công cụ khác như docker, .. thì dùng child process, còn khi nào bác cần xử lý dữ liệu data trong project phải lặp lên đến cả triệu element(đại loại thế) thì nên dùng worker threads để tránh block event loop

AvatarXuân Hoài Tống2 năm trước

@Phương mình thì thấy worker thread và child process có cách dùng tương đương nhau. Có điều worker được ra sau và nó dùng ít tài nguyên hơn so với child nên nó được khuyên dùng hơn.

AvatarTùng Nguyễn3 năm trước

Thực ra node là đa luồng ở libuv vậy thì tại sao lại phải tạo ra worker thread để làm gì?

Trả lờiBình luậnAvatarTùng Nguyễn3 năm trước

Thực ra node là đa luồng ở libuv vậy thì tại sao lại phải tạo ra worker thread để làm gì?

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiAvatarVăn Thành Phan3 năm trước

Nhưng luồng chính vẫn phải wait nhiều hơn nếu chỉ 1 main thread chứ bác

AvatarXuân Hoài Tống3 năm trước

Bác ở dưới nói đúng rồi đấy b Tùng, node có thể đa luồng ở background nhưng luồng chính chỉ có một và nó xử lý đồng bộ mã của js

AvatarNhí Nhố Tí3 năm trước

Quá tuyệt vời quá nai xừ 😍

Trả lờiBình luậnAvatarNhí Nhố Tí3 năm trước

Quá tuyệt vời quá nai xừ 😍

Ẩn danhẨn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửi

Xin chào, tôi là Hoài.

Bấm vào để làm quen!

Tống Xuân Hoài

Nâng cấp tài khoản

Rẻ nhất

Premium

🔥 28.000đ/tháng84.000đ/tháng
  • Trải nghiệm không quảng cáo
  • Tóm tắt bài viết
  • Biểu tượng cao cấp
  • Phiên bản tối giản
Giá trị nhất

Premium Plus

85.000đ/tháng255.000đ/tháng
  • Tất cả tính năng của Premium
  • 3 thẻ bài viết / tháng

Premium

28.000đ/tháng7 ngày dùng thử miễn phíKích hoạt dùng thửKhi mua, bạn đồng ý vớiĐiều khoản dịch vụ

Từ khóa » đa Luồng Trong Nodejs