2 điểm bởi GN⁺ 2023-09-09 | 1 bình luận | Chia sẻ qua WhatsApp
  • Bài viết này thảo luận về những thách thức khi sử dụng Rust cho phần mềm không gian người dùng có mức độ đồng thời quy mô lớn.
  • Mô hình bất đồng bộ của Rust được thiết kế để xử lý hai khái niệm cốt lõi của điện toán hiện đại: đồng thời và song song.
    • Song song bao gồm việc chạy mã cùng lúc trên nhiều CPU.
    • Đồng thời bao gồm việc tách vấn đề ra và chia nó thành các phần độc lập để thực thi không phụ thuộc thứ tự hoặc theo thứ tự từng phần.
  • Bài viết nhấn mạnh những hạn chế của việc dùng nhiều tiến trình cho tính đồng thời do chi phí giao tiếp liên tiến trình cao.
  • Luồng, tức các tiến trình chia sẻ cùng một vùng nhớ, được đưa ra như một phương án thay thế, nhưng có thể dẫn đến các vấn đề phức tạp như race condition và deadlock.
  • Bài báo năm 1978 của Tony Hoare, "Communicating Sequential Processes", đề xuất sử dụng hàng đợi hoặc channel để các luồng gửi thông điệp cho nhau, mang lại nhiều ưu điểm như tính cô lập kiểu tiến trình và khả năng gỡ lỗi dễ hơn.
  • Thư viện chuẩn của Rust có channel trong std::sync::mpsc::sync_channel.
  • Tuy nhiên, với những bài toán đòi hỏi mức độ đồng thời rất cao, như máy chủ web kết nối với hàng chục nghìn người dùng, luồng có thể là chưa đủ.
  • Rust dùng mô hình "async/await" cho các tình huống này, trong đó khi một hàm được đánh dấu bất đồng bộ, nó sẽ trả về một future hoặc promise và có thể được chờ để tạo ra kết quả.
  • Dù có nhiều ưu điểm, Rust bất đồng bộ vẫn đi kèm các thách thức, chẳng hạn nhu cầu phải thuyết phục trình biên dịch rằng mọi thứ sẽ ổn; điều này có thể khó hơn so với dùng luồng thô.
  • Việc sử dụng "đếm tham chiếu nguyên tử" hay Arc được đề xuất như một giải pháp, nhưng đây không phải liều thuốc vạn năng vì nó có thể dẫn tới các vấn đề tương tự như với bộ gom rác.
  • Bài viết kết luận rằng, dù Rust có thế mạnh ở các lĩnh vực khác, nó có thể không phải là công cụ tối ưu cho phần mềm không gian người dùng có mức độ đồng thời quy mô lớn.

1 bình luận

 
GN⁺ 2023-09-09
Ý kiến trên Hacker News
  • Tác giả đang phát triển một client metaverse hiệu năng cao bằng Rust, cần xử lý lượng lớn dữ liệu theo thời gian thực.
  • Dự án của tác giả sử dụng nhiều luồng cho các tác vụ khác nhau như render đồ họa, xử lý sự kiện mạng và tải tài nguyên.
  • Rust đã mang lại lợi ích cho dự án này, và tác giả cho biết bình thường họ gặp sự cố sập liên quan đến bộ nhớ khoảng một lần mỗi năm do mã "unsafe" của người khác.
  • Tác giả phê phán rằng Rust không có race condition nhưng không có nghĩa là không có deadlock, và đề xuất cần có một trình phân tích deadlock tĩnh.
  • Tác giả chỉ trích việc async được dùng rộng rãi trong Rust, cho rằng nó không phù hợp với các tác vụ bị ràng buộc bởi tính toán và không tương thích với các luồng chạy ở nhiều mức ưu tiên.
  • Tác giả cho rằng mô hình sở hữu đơn nhất của Rust, dù là nhu cầu phổ biến khi có tham chiếu ngược, lại quá khó để triển khai.
  • Tác giả tin rằng hệ sinh thái game của Rust chưa sẵn sàng cho việc phát triển game nghiêm túc, dẫn chứng là sự thiếu vắng đồ họa không mang tính đồ chơi trong Rust.
  • Các bình luận khác đồng ý rằng async Rust nhiều thách thức và thường không cần thiết, đồng thời cho rằng cách tiếp cận của Go là làm mọi thứ thành sync và chỉ dùng một kênh async có thể tốt hơn.
  • Một số người bình luận chỉ trích việc async được dùng rộng rãi trong hệ sinh thái Rust, cho rằng điều này buộc chương trình phải trở thành async từ đầu đến cuối hoặc phải phụ thuộc vào crate tokio cho rất nhiều thứ.
  • Một số người bình luận cho rằng tính năng async của Rust vẫn đang trong quá trình phát triển, nên còn quá sớm để chỉ trích trạng thái hiện tại của nó.
  • Một người bình luận cho rằng Arc trong Rust không phải là thứ không thể biết trước, mà được quyết định bởi nơi và cách bạn nắm giữ nó, đồng thời cho rằng tác giả đang cố ép mô hình tư duy cũ của mình vào Rust.
  • Một số người bình luận nhìn chung phản đối việc sử dụng async/await, cho rằng nó chia ngôn ngữ và hệ sinh thái thành hai nửa và sẽ gây ra vấn đề dài hạn.
  • Một người bình luận cho rằng primitive đúng đắn cho tính đồng thời là Communicating Sequential Processes của Hoare, được ánh xạ sang green threads như cách Java (từ JDK17 trở đi - Java Virtual Threads), Go và Kotlin triển khai.
  • Một người bình luận cho rằng dùng các crate unsafe như async-scoped để bắt phần lớn các lỗi lẽ ra sẽ xuất hiện nếu viết bằng C++ là một sự thỏa hiệp hợp lý.