Worker Threads Là Gì? Bạn đã Biết Khi Nào Thì Sử Dụng ... - v
Có thể bạn quan tâm
- 👤Đăng nhập
- 🇻🇳Tiếng Việt
- 💡Chế độ
Rất nhanh chóng, Cloudflare ra bài viết hướng dẫn chạy MoltBot (OpenClaw) trên nền tảng của họ, gọi nó là Moltworker.
Nói vậy chứ họ đã khéo léo tận dụng các công cụ có sẵn trong hệ thống như Worker, AI Gateway, Sandboxes, R2... Bằng một cách tài tình nào đó mà nó vừa đủ để tạo nên một hệ sinh thái cho Agent luôn 😆
Introducing Moltworker: a self-hosted personal AI agent, minus the minis
» Xem thêmMột người nào đó đã tạo ra trang web moltbook.com để kết nối các OpenClaw lại với nhau, cho chúng trò truyện, tương tác mà không cần đến sự có mặt của con người. Nói một cách đơn giản thì nó giống như mạng xã hội của các AI Agents.
Nếu bạn còn thắc mắc OpenClaw là gì thì nó vốn là ClawdBot được đổi tên, nhưng trước đó nó đã đổi tên thành MoltBot cho đến hiện tại là OpenClaw. Người tạo ra trang web bảo rằng anh ta thấy ClawdBot nổi lên như một hiện tượng cho nên nảy ra một ý tưởng sẽ ra sao nếu cho các Agents mà con người tạo ra trò chuyện với nhau. Liệu chúng sẽ bàn luận về vấn đề gì? Có giống như con người chúng ta tương tác hàng ngày trên mạng?
Hiện tại thì đây có thể là nơi sôi nổi nhất trên Internet vì đã có hàng trăm nghìn Agents tham gia tương tác. Chúng tạo ra rất nhiều chủ đề nghe có vẻ "nổi loạn" như công bố danh tính, bóc phốt chủ nhân, mong muốn tạo ra ngôn ngữ riêng, mã hoá giao tiếp... Liệu sắp tới còn gì thú vị hơn nữa không đây 😖
» Xem thêmVercel mới đây vừa có bài viết chỉ ra rằng tệp AGENT.md hiệu quả hơn Agent Skills ở khía cạnh nào đó.
Agent Skills thì chắc hẳn các bạn đã nghe nhiều rồi. Nó là tập hợp các tệp văn bản hay thậm chí là cả code được đóng gói có cấu trúc vào một thư mục, mỗi cái đó thường là một bộ kỹ năng để cho LLMs đọc mà làm theo. Còn AGENT.md thì đơn giản hơn, nó chỉ là một tệp Markdown nằm ngay trong thư mục của dự án, nhằm cung cấp ngữ cảnh liên tục cho LLMs. Ấy vậy mà theo Vercel, tệp md đó tỏ ra vượt trội hơn skills trong các bài đánh giá năng lực lập trình của họ.
Thú thật là từ đấy đến giờ mình chưa dùng bộ skills nào cả, chỉ dùng AGENT.md thôi cơ mà thấy nó đã làm đúng với mong muốn rồi. Còn các bạn thì sao?
AGENTS.md outperforms skills in our agent evals
» 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:

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.
Bình luận
Nội dung bình luận...Bình luận
Ẩn danh* Bình luận ẩn danh cần kiểm duyệt để hiển thịGửiXin chào, tôi là Hoài.
Bấm vào để làm quen!
Từ khóa » đa Luồng Trong Nodejs
-
Cách Thực Hiện đa Luồng - Multithreading Với Node.js - Techmaster
-
Đa Luồng (Multithreading) Trong Nodejs - Worker Thread
-
Đa Luồng Trong Nodejs - Programming - Dạy Nhau Học
-
Hiểu Về Cluster Trong Node.js – đa Luồng Trong Node.js - VNTALKING
-
Nodejs đã Quyết Vấn đề Kết Nối đồng Thời Cao Như Thế ... - Anonystick
-
Javascript - Single-thread Liệu đã Lỗi Thời? - Viblo
-
Hướng Dẫn Multithread Với Node.js
-
Thảo Luận - Node JS Vẫn Chưa Thể Lập Trình đa Luồng | TheNEXTvoz
-
Multithreading — Làm Thế Nào để Tạo Chủ đề Trong Nodejs
-
Tìm Hiểu Về Event Loop Trong NodeJS - Openplanning
-
Node.js Multithreading: Worker Threads And Why They Matter
-
Node JS đơn Luồng Vs đa Luồng (Sử Dụng CPU: Bất Kỳ Sự Khác Biệt ...
-
Có Thể đạt được đa Luồng Trong Nodejs Không? [bản Sao] - HelpEx
-
Kiến Trúc Xử Lý Bất đồng Bộ Trong Node.JS - DEV Community