2 điểm bởi GN⁺ 2024-03-04 | 1 bình luận | Chia sẻ qua WhatsApp

Khả năng có lỗi của std::shared_mutex trên Windows

  • Một nhóm phần mềm đã phát hiện hành vi bất ngờ liên quan đến std::shared_mutex trên Windows.
  • Vấn đề này chỉ xảy ra với MSVC, không xuất hiện trên MinGW hay các nền tảng khác.
  • Khi luồng chính giành được khóa độc quyền rồi nhiều luồng con cố giành khóa chia sẻ, cứ khoảng 1 trên 1000 lần sẽ xảy ra "deadlock".
  • Khi deadlock xảy ra, chỉ đúng 1 luồng con giành được khóa chia sẻ thành công, còn các luồng con khác bị chặn vĩnh viễn tại lock_shared().
  • Vấn đề này được quan sát thấy khi dùng std::shared_mutex, std::shared_lock/std::unique_lock hoặc khi gọi trực tiếp các hàm SRW.

Ví dụ mã và tái hiện lỗi

  • Có cung cấp đoạn mã đơn giản có thể tái hiện vấn đề.
  • Đoạn mã lặp lại quá trình trong đó luồng chính giành khóa độc quyền, nhiều luồng con giành khóa chia sẻ rồi giải phóng nó.
  • Đoạn mã này chỉ cho thấy lỗi liên quan đến std::shared_mutex trên triển khai Windows MSVC.

Ý kiến của chuyên gia

  • Nhà phát triển STL cho biết vấn đề này có vẻ là lỗi của Windows API.
  • Đã có thảo luận về các bước phù hợp để báo cáo lỗi, và nhà phát triển STL đã báo cáo lỗi này nội bộ.
  • Những người dùng khác đã điều tra chi tiết vấn đề và góp phần thu hẹp nguyên nhân xuống một lỗi cụ thể trong triển khai SRWLock.

Ý kiến của GN⁺

  • Bài viết này cung cấp thông tin đặc biệt quan trọng với các lập trình viên C++, vì lỗi tiềm ẩn trong std::shared_mutex có thể ảnh hưởng đến cơ chế đồng bộ hóa của các ứng dụng đa luồng.
  • Nếu lỗi được xác nhận, điều này có thể ảnh hưởng đến mức độ tin cậy đối với triển khai của thư viện chuẩn C++. Các lập trình viên cần nhận thức được vấn đề này và có thể phải cân nhắc các cơ chế đồng bộ hóa thay thế.
  • Vấn đề này có thể đặc biệt quan trọng trong các hệ thống hiệu năng cao hoặc thời gian thực, nơi deadlock có thể gây ra hậu quả nghiêm trọng.
  • Trước khi áp dụng công nghệ này, các lập trình viên nên thực hiện kiểm thử rộng rãi trên nền tảng và trình biên dịch liên quan để xác nhận rằng không có kiểu lỗi như vậy.
  • Để xử lý những vấn đề như thế này, các lập trình viên có thể cân nhắc các thư viện đồng bộ hóa thay thế như Boost. Vì Boost đã được kiểm thử rộng rãi và được sử dụng trên nhiều nền tảng, nó có thể cung cấp một phương án thay thế ổn định cho các vấn đề kiểu này.

1 bình luận

 
GN⁺ 2024-03-04
Ý kiến trên Hacker News
  • Một người dùng thắc mắc vì sao một vấn đề cơ bản như vậy lại không bị phát hiện trong thời gian dài và nhắc đến câu trả lời thuyết phục mà người khác đã đưa ra. Họ chỉ ra rằng có trường hợp một luồng đang cố lấy khóa ở chế độ chia sẻ lại vô tình giành được khóa ở chế độ độc quyền. Điều này xảy ra do sự chồng lấp của phép toán kiểm tra và thiết lập bit nguyên tử khi luồng lấy khóa chia sẻ và luồng nhả khóa độc quyền chạy đồng thời.

    • Một người dùng giải thích rằng họ có đoạn mã tái hiện trong đó mọi luồng khác đều chờ để lấy khóa chia sẻ trong khi một luồng đang lấy khóa chia sẻ, và vì vậy nếu một luồng công việc nào đó vô tình lấy được khóa độc quyền thì có thể dẫn đến deadlock. Trong các trường hợp sử dụng thông thường, các luồng không chờ nhau nên deadlock không xảy ra.
  • Một người dùng khác nói rằng họ không ngạc nhiên trước những bug tinh vi xuất hiện trong khóa Reader/Writer, đồng thời chia sẻ kinh nghiệm từng làm phần hiện thực nội bộ dựa trên Win32 trước thời kỳ C++11 và std::shared_mutex. Vì có trải nghiệm tệ với khóa chia sẻ, họ cho biết sẽ tránh dùng chúng trừ khi thật sự cần thiết.

    • Một người dùng chia sẻ trải nghiệm tiêu cực với khóa chia sẻ, nói rằng hiệu năng của std::shared_mutex kém hơn đáng kể so với std::mutex, đến mức double buffering còn nhanh hơn.
  • Một người dùng chỉ ra rằng tiêu đề gây hiểu nhầm, và bug thực tế nằm ở khóa slim reader/writer (SRW) của Windows API; nó được phát hiện vì std::shared_mutex được hiện thực bằng khóa SRW. Một nhân viên Microsoft xác nhận rằng bug này đã được chuyển nội bộ tới nhóm Windows API.

    • Một người dùng chỉ ra tiêu đề gây hiểu nhầm và nói rằng vấn đề thực sự nằm ở khóa SRW của Windows API, đồng thời nhắc rằng một nhân viên Microsoft đã xác nhận bug đã được báo cáo.
  • Một người dùng thắc mắc liệu cùng vấn đề này có xảy ra trong phần hiện thực của WINE hay không, và nói rằng họ cũng muốn thử trên bản cài XP tùy biến của mình. Trên bản cài đó, họ đã thêm nhiều phần mở rộng, bao gồm SRW API, và đã vá kernel để sửa một race condition gây deadlock trong keyed event API vốn dựa trên phần hiện thực SRW.

    • Một người dùng thắc mắc liệu phần hiện thực của WINE có gặp cùng vấn đề hay không, đồng thời nói rằng họ muốn thử trên bản XP tùy biến của mình. Bản cài này đã được bổ sung nhiều phần mở rộng, bao gồm SRW API, và kernel cũng đã được vá để sửa race condition gây deadlock trong keyed event API dựa trên phần hiện thực SRW.
  • Có ý kiến chỉ ra rằng chương trình có bug. Nó trộn lẫn biến non-atomic và biến atomic để dùng trong vòng lặp kiểm tra yield(), trong khi biến non-atomic không đảm bảo tính nhất quán bộ nhớ đệm giữa các luồng. Điều này có thể khiến vòng lặp chạy mãi mãi.

    • Một người dùng chỉ ra bug trong chương trình và giải thích vấn đề phát sinh từ việc trộn lẫn biến non-atomic với biến atomic. Họ nói rằng biến non-atomic không đảm bảo tính nhất quán bộ nhớ đệm nên vòng lặp có thể chạy vô hạn.
  • Một người dùng nói rằng bug này có từ tận phiên bản Vista năm 2008 và bày tỏ sự ngạc nhiên khi suốt thời gian dài như vậy không ai phát hiện ra. Họ nhắc rằng trong cách dùng rwlock thông thường, có thể xuất hiện các trường hợp ngẫu nhiên không lấy được khóa chia sẻ, nhưng không dẫn đến deadlock.

    • Một người dùng nói rằng bug này truy ngược đến phiên bản Vista và bày tỏ sự ngạc nhiên vì nó không bị phát hiện trong thời gian dài. Họ nói rằng với cách dùng rwlock thông thường, deadlock không xảy ra nhưng vẫn có thể có trường hợp không lấy được khóa chia sẻ.
  • Một người dùng nói rằng việc báo bug cho Windows API là cực kỳ khó, và dù họ được hướng dẫn báo qua Feedback Hub, cách đó hầu như không hiệu quả. Người này cho biết đã báo một bug trong đó SRWLOCK có thể rơi vào deadlock khi nhiều luồng đọc cố gắng cùng lúc giành quyền sở hữu chia sẻ sau khi chủ sở hữu độc quyền đã nhả quyền sở hữu.

    • Một người dùng nói rằng việc báo bug cho Windows API rất khó và chỉ trích việc báo qua Feedback Hub là không hiệu quả. Họ chia sẻ rằng mình đã từng báo một bug liên quan đến SRWLOCK.
  • Một người dùng hồi tưởng rằng trước đây khi mua sản phẩm MS, họ có thể nhận được một support incident, và nếu phát hiện ra bug thật thì support incident đó sẽ được hoàn tiền. Họ nói đây là một hệ thống tốt, vừa hữu ích cho lập trình viên vừa giúp MS nhận được phản hồi để phát hiện vấn đề thực tế và cải thiện tài liệu. Họ tự hỏi liệu chương trình này còn tồn tại hay không.

    • Một người dùng hồi tưởng về các support incident từng đi kèm sản phẩm MS và nói rằng hệ thống này có lợi cho cả lập trình viên lẫn MS. Họ tự hỏi liệu chương trình đó hiện nay còn tồn tại không.
  • Cuối cùng, một người dùng bày tỏ sự thất vọng trước việc báo bug cho Windows API quá khó khăn.

    • Một người dùng bày tỏ sự thất vọng về sự khó khăn trong việc báo bug cho Windows API.