2P by neo 3달전 | favorite | 댓글 1개

Windows에서 std::shared_mutex의 버그 가능성

  • 한 소프트웨어 팀이 Windows에서 std::shared_mutex와 관련된 예상치 못한 동작을 발견함.
  • 이 문제는 MSVC에서만 발생하며, MinGW나 다른 플랫폼에서는 발생하지 않음.
  • 주요 스레드가 독점 잠금을 획득한 후 여러 자식 스레드가 공유 잠금을 획득하려고 할 때, 약 1000번 중 1번 꼴로 "데드락"이 발생함.
  • 데드락이 발생하면 정확히 1개의 자식 스레드만 공유 잠금을 성공적으로 획득하고, 나머지 자식 스레드는 lock_shared()에서 영원히 차단됨.
  • 이 문제는 std::shared_mutex, std::shared_lock/std::unique_lock 또는 직접 SRW 함수를 호출할 때 관찰됨.

코드 예제와 버그 재현

  • 문제를 재현할 수 있는 간단한 코드가 제공됨.
  • 코드는 주 스레드가 독점 잠금을 획득하고, 여러 자식 스레드가 공유 잠금을 획득한 후 이를 해제하는 과정을 반복함.
  • 이 코드는 Windows MSVC 구현에서만 std::shared_mutex와 관련된 버그를 보여줌.

전문가의 의견

  • STL 개발자는 이 문제가 Windows API 버그로 보인다고 언급함.
  • 버그를 보고하기 위한 적절한 단계에 대한 논의가 있었으며, STL 개발자가 내부적으로 버그를 보고함.
  • 다른 사용자들은 이 문제를 자세히 조사하고, SRWLock 구현의 특정 버그를 좁혀내는 데 기여함.

GN⁺의 의견

  • 이 기사는 C++ 개발자들에게 특히 중요한 정보를 제공함. std::shared_mutex의 잠재적인 버그는 멀티스레딩 애플리케이션의 동기화 메커니즘에 영향을 줄 수 있기 때문임.
  • 버그가 확인되면, 이는 C++ 표준 라이브러리의 구현에 대한 신뢰도에 영향을 미칠 수 있음. 개발자들은 이러한 문제를 인지하고 대안적인 동기화 메커니즘을 고려해야 할 수도 있음.
  • 이 문제는 특히 고성능이나 실시간 시스템에서 중요할 수 있음. 이러한 시스템에서는 데드락이 치명적인 결과를 초래할 수 있기 때문임.
  • 이 기술을 도입하기 전에, 개발자들은 해당 플랫폼과 컴파일러에 대한 광범위한 테스트를 수행하여 이러한 유형의 버그가 없는지 확인해야 함.
  • 이러한 문제를 해결하기 위해, 개발자들은 Boost 라이브러리와 같은 대체 동기화 라이브러리를 고려할 수 있음. Boost는 광범위하게 테스트되고 많은 플랫폼에서 사용되므로, 이러한 문제에 대한 안정적인 대안을 제공할 수 있음.
Hacker News 의견
  • 한 사용자는 기본적인 문제가 오랫동안 발견되지 않은 이유에 대해 궁금해하며, 다른 사용자가 제공한 설득력 있는 답변을 언급함. 공유 모드로 잠금을 시도하는 스레드가 실수로 독점 모드로 잠금을 얻을 수 있는 경우가 있음을 지적함. 이는 공유 모드 획득 스레드와 독점 모드 해제 스레드가 동시에 실행될 때 발생하는 원자적 비트 테스트 및 설정 연산의 중첩 때문임.

    • 한 사용자는 공유 잠금을 획득하는 동안 다른 모든 스레드가 공유 잠금을 획득하기를 기다리는 재현 코드가 있으며, 이로 인해 어떤 작업 스레드가 실수로 독점 잠금을 얻게 되면 교착 상태에 빠질 수 있음을 설명함. 일반적인 사용 사례에서는 스레드가 서로 기다리지 않으므로 교착 상태가 발생하지 않음.
  • 또 다른 사용자는 Reader/Writer 잠금에서 발생하는 미묘한 버그에 놀라지 않는다고 언급하며, C++11과 std::shared_mutex 이전에 Win32 기반으로 내부 구현을 작업한 경험을 공유함. 공유 잠금에 대한 나쁜 경험으로 인해 절대적으로 필요하지 않는 한 피하려고 함을 밝힘.

    • 한 사용자는 공유 잠금에 대한 부정적인 경험을 공유하며, std::shared_mutex의 성능이 std::mutex에 비해 현저히 떨어져 데이터를 더블 버퍼링하는 것이 더 빠르다고 언급함.
  • 한 사용자는 제목이 오해의 소지가 있다고 지적하며, 실제 버그는 Windows API의 slim reader/writer (SRW) 잠금에 있으며, std::shared_mutex가 SRW 잠금을 사용하여 구현되었기 때문에 발견된 것임을 설명함. 마이크로소프트 직원이 버그가 Windows API 팀에 내부적으로 제기되었다고 확인함.

    • 한 사용자는 오해의 소지가 있는 제목에 대해 지적하며, 실제 문제는 Windows API의 SRW 잠금에 있으며, 마이크로소프트 직원이 버그가 제기되었다고 확인함을 언급함.
  • 한 사용자는 WINE의 구현에서도 동일한 문제가 발생하는지 궁금해하며, 자신의 맞춤형 XP 설치에서도 테스트하고 싶다고 언급함. 해당 설치에서는 SRW API를 포함한 여러 확장을 추가했으며, SRW 구현에 기반한 keyed event API에서 교착 상태를 일으키는 경쟁 조건을 수정하기 위해 커널을 패치했다고 함.

    • 한 사용자는 WINE 구현에서도 같은 문제가 발생하는지 궁금하며, 자신의 맞춤 XP 설치에서 테스트하고 싶다고 언급함. 이 설치에서는 SRW API를 포함한 여러 확장을 추가하고, SRW 구현에 기반한 keyed event API에서 교착 상태를 일으키는 경쟁 조건을 수정하기 위해 커널을 패치했다고 함.
  • 프로그램에 버그가 있음이 지적됨. atomic이 아닌 변수와 atomic 변수를 혼용하여 yield() 검사 루프에서 사용하고 있으며, atomic이 아닌 변수는 다른 스레드에 대한 캐시 일관성을 보장하지 않음. 이로 인해 루프가 영원히 실행될 수 있음.

    • 한 사용자는 프로그램의 버그를 지적하며, atomic이 아닌 변수와 atomic 변수를 혼용하여 사용함으로써 발생하는 문제를 설명함. atomic이 아닌 변수는 캐시 일관성을 보장하지 않아 루프가 무한히 실행될 수 있음을 언급함.
  • 한 사용자는 이 버그가 2008년 Vista 버전까지 거슬러 올라가며, 이렇게 오랜 시간 동안 아무도 이 버그를 발견하지 못한 것에 대해 놀라움을 표함. 일반적인 rwlock 사용에서는 공유 잠금을 획득하지 못하는 무작위 사례가 발생할 수 있으나 교착 상태는 발생하지 않음을 언급함.

    • 한 사용자는 이 버그가 Vista 버전까지 거슬러 올라가며, 오랜 시간 동안 발견되지 않은 것에 대해 놀라움을 표함. 일반적인 rwlock 사용에서는 교착 상태가 발생하지 않지만 공유 잠금을 획득하지 못하는 사례가 발생할 수 있음을 언급함.
  • 한 사용자는 Windows API에 대한 버그를 보고하는 것이 매우 어렵다고 언급하며, Feedback Hub를 통해 보고하라는 지시를 받지만, 이는 거의 효과가 없다고 비판함. 해당 사용자는 SRWLOCK이 독점 소유자가 소유권을 해제한 후 여러 읽기 스레드가 공유 소유권을 함께 획득하려고 할 때 교착 상태에 빠질 수 있다는 버그를 보고함.

    • 한 사용자는 Windows API에 대한 버그 보고가 매우 어렵다고 언급하며, Feedback Hub를 통한 보고가 효과적이지 않다고 비판함. SRWLOCK 관련 버그를 보고한 사실을 공유함.
  • 한 사용자는 과거에 MS 제품을 구매하면 지원 사건을 받을 수 있었으며, 실제 버그를 발견하면 지원 사건이 환불되었다고 회상함. 이는 개발자에게 유익했고, MS에게도 실제 문제를 발견하고 문서를 개선할 수 있는 피드백을 제공하는 좋은 시스템이었음을 언급함. 이 프로그램이 여전히 존재하는지 궁금해함.

    • 한 사용자는 과거 MS 제품에 포함된 지원 사건에 대해 회상하며, 이 시스템이 개발자와 MS 모두에게 유익했다고 언급함. 현재 이 프로그램이 존재하는지 궁금해함.
  • 마지막으로 한 사용자는 Windows API에 대한 버그를 보고하는 것이 어렵다는 점에 대해 실망감을 표현함.

    • 한 사용자는 Windows API에 대한 버그 보고의 어려움에 대해 실망감을 표현함.