Ngăn chặn tình trạng chết luồng – các phương pháp hay nhất

lập trình


Tôi đang tìm kiếm thêm thông tin về cách ngăn chặn tình trạng chết đói/chặn/chạy đua luồng trong một ứng dụng hoặc dịch vụ có thể chạy đồng thời tới 200 luồng trên nhiều bộ xử lý/lõi.

Hầu hết các ví dụ tôi tìm thấy trực tuyến đều cho thấy cách phối hợp tối đa giữa 3 hoặc 4 luồng và tôi đang lên kế hoạch cho một ứng dụng sẽ có hàng trăm luồng.

Tôi đã tạo các ứng dụng chạy tới 30 luồng nhưng khi vượt xa mức đó, tôi lo lắng về việc một số luồng không nhận được bất kỳ thời gian CPU nào, chưa kể đến việc đồng bộ hóa.

Tôi có thể tìm thấy một số bài viết và blog thực sự tốt ở đâu?
Những cuốn sách hay nhất về chủ đề này là gì?
Có rất nhiều sách và bài viết về chủ đề này, tôi đang tìm kiếm những tài liệu có nhiều thông tin và hướng dẫn nhất nhưng không được trình bày bằng ngôn ngữ kỹ thuật vượt quá hiểu biết của tôi.

Tất cả các đề xuất đều được đánh giá cao.

Giải pháp 1

Có quá nhiều kịch bản cần đề cập nên không thể trả lời câu hỏi của bạn.

Tuy nhiên, việc sử dụng nhiều luồng hoạt động hơn số lượng lõi thường phản tác dụng. Bạn chỉ có thể hưởng lợi từ việc sử dụng nhiều luồng hơn số lõi nếu hầu hết các luồng thường muốn ngủ, chẳng hạn như bằng cách chờ một số thao tác IO như lệnh gọi recv() nhận dữ liệu từ mạng. Ngay cả trong trường hợp đó, bạn muốn chủ động kiểm soát số lượng luồng thực thi song song, vì vậy, việc bắt đầu 200 luồng với hy vọng rằng chỉ 4 luồng trong số đó *muốn* chạy song song nếu bạn có 4 lõi không phải là cách thực hành tốt.

Nếu bạn phải chạy 200 tác vụ song song luôn hoạt động thì tốt hơn hết bạn chỉ nên tạo số lượng luồng bằng số lõi và chia các tác vụ thành các công việc nhỏ. Bạn thực hiện các công việc nhỏ này trên các luồng của mình theo bất kỳ thứ tự nào bạn muốn bằng cách đưa chúng vào hàng đợi công việc mà từ đó các luồng của bạn sẽ kéo chúng ra từng cái một. Điều này gần như đã có lịch trình riêng của bạn. Một kỹ thuật thường mang lại giải pháp phức tạp hơn giải pháp trước đó là sử dụng các luồng/coroutine màu xanh lá cây (api ucontext POSIX không được dùng nữa trên một số bản phân phối linux và api cáp quang trên windows).

Bằng cách sử dụng các luồng màu xanh lá cây, bạn có thể chia một luồng thành nhiều luồng màu xanh lá cây và thực hiện các tác vụ chuyển đổi/hợp tác giữa các luồng màu xanh lá cây này một cách rõ ràng trong không gian người dùng. Giả sử bạn có 4 lõi. Sau đó, bạn có thể bắt đầu 4 luồng và nếu bạn chia mỗi luồng thành 100 luồng xanh thì bạn có 400 luồng xanh nhưng chỉ có 4 trong số chúng thực thi song song tại bất kỳ thời điểm nào và bạn có thể viết trình lập lịch của riêng mình vì bạn có quyền kiểm soát nhiệm vụ chuyển đổi giữa các chủ đề màu xanh lá cây.

Ví dụ, viết một máy chủ web sử dụng các luồng màu xanh lá cây có lợi ích sau: mã cho các triển khai đa luồng thông thường và triển khai luồng không đồng bộ/xanh có thể sử dụng cùng một mã servlet nếu được viết tốt (vì bạn có thể đặt tác vụ chuyển đổi sang triển khai của riêng bạn theo cách khác). các lệnh gọi hàm chặn như các hàm đọc/ghi ổ cắm và việc triển khai các lệnh gọi hàm chặn tương tự ở chế độ đa luồng thực tế đang gọi các hàm tương đương của hệ điều hành chặn).

コメント

タイトルとURLをコピーしました