2012-08-30 6 views
0

유스 케이스를 기준으로 WinRT 개체에 대한 참조 횟수가 스레드로부터 안전하다는 인상하에있었습니다. 그러나 나는 설명 할 수있는 다른 방법을 모르는 버그에 빠져 들었다. 예를 들어, 다음 코드는 매우 빠르게 충돌 :C++/CX WinRT 포인터의 참조 횟수 스레드 안전성

ref class C sealed { 
public: 
    C() { } 
    virtual ~C() {} 
}; 

[Windows::Foundation::Metadata::WebHostHidden] 
public ref class MainPage sealed { 
public: 
    MainPage() : _latest(nullptr) { 
     InitializeComponent(); 
     Windows::System::Threading::ThreadPool::RunAsync(
      ref new Windows::System::Threading::WorkItemHandler(
       this, 
       &MainPage::SetLatest)); 
     Windows::System::Threading::ThreadPool::RunAsync(
      ref new Windows::System::Threading::WorkItemHandler(
       this, 
       &MainPage::OnRendering)); 
    } 
    virtual ~MainPage(){} 
private: 
    C^ _latest; 
    void SetLatest(Windows::Foundation::IAsyncAction^ operation){ 
     while (true) { 
      _latest = ref new C(); 
     } 
    } 
    void OnRendering(Windows::Foundation::IAsyncAction^ operation) { 
     while (true) { 
      auto c = _latest; 
     } 
    } 
}; 

는 WinRT의 포인터 제대로 계산 참조가 될 예정 (C^ 같은 심판 클래스 형식 즉) 경우 읽기/쓰기가 경주입니까? 내가 알지 못하는 별도의 문제가있어이 충돌이 발생 했습니까?

답변

5

ref class 개체의 참조 횟수를 변경하면 동기화되지만 T^ 개체는 변경되지 않습니다.

_latest에 액세스하는 두 개의 스레드가 있고이 스레드 중 하나가 _latest을 수정 중이므로 _latest에 대한 액세스를 동기화해야합니다. std::mutex을 사용하십시오.

+0

그러면 그 점을 설명합니다. 이것을 설명하는 문서에 링크 할 수 있습니까? –

+1

어떤 부분을 문서화하고 있습니까? 'ref 클래스 '는 COM 클래스 타입이므로 모든 COM 스레딩 규칙을 따라야합니다. 'T ^'는 외부 동기화가 필요한 다른 유형과 다르지 않습니다. –