나는 std :: mutex를 최근에 사용 해왔고 멤버로 std :: mutex가있는 객체를 삭제할 때 패턴/디자인 안내서를 찾고있다. 이 문제는 뮤텍스 (모니터 함수, 임계 구역 등)를 사용하는 공용 함수로서 객체가 삭제 될 때 발생하며이 객체가 삭제 될 때 스레드가 여전히 뮤텍스를 기다리고있을 수 있습니다. std :: mutex 다른 스레드에 의해 잠겨있는 동안 정의되지 않은 동작이 삭제되어 문제가 발생합니다.회원 계정을 안전하게 삭제하는 방법 :: mutex?
이 경우 일반적으로 받아 들일 수있는 패턴이 무엇인지 알고 싶습니다. 또는 이것이 잘못된 코딩 스타일로 간주되면이 디자인을 피하는 방법, 즉 뮤텍스 메소드가 아직 대기중인 객체를 삭제하지 마십시오.
예 :
//a public method that uses mutex.
IAsyncAction^ XInputBase::flushTask()
{
return create_async([this](){
_monitorMutex.lock();
if (_readyToFlush && !_noMoreFlush) {
//should flush only once, block additional flush signals.
_noMoreFlush = true;
_monitorMutex.unlock();
//actually flush
concurrency::task<void> UITask = concurrency::create_task(Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([=]()
{
onFlush();
})));
}
else {
_needToFlush = true;
_monitorMutex.unlock();
}
});
}
시도 솔루션 : 소멸자 모든 대기 스레드가 처리 된 후 완전히 잠금을 해제하기 위해 뮤텍스를 기다리고. 뮤텍스 밖의 플래그를 설정하여 메소드를 구현 했으므로 메소드의 모든 스레드가 종료되거나 뮤텍스를 기다리고 있습니다. 그렇다면 std :: mutex를 소멸자에서 마지막으로 잠갔습니다. 주어진 std :: mutex가 공평하다는 점을 감안할 때, 다른 대기중인 스레드가 처리 된 후 소멸자가 마지막으로 잠금 해제되어야하고 객체를 파괴해야합니다.
std :: mutex가 대부분의 플랫폼에서 공정성을 보장하지 않기 때문에 이것은 작동하지 않습니다.
일종의 해결책 : 개체를 ref 클래스 또는 다른 참조 계산 개체 (스마트 포인터)로 구현하십시오. 그런 다음 객체에 대한 강력한 참조를 보유하고있는 lamda로 동시 메소드를 구현하십시오. 이 객체를 포함하는 다른 모든 객체가 삭제되고 뮤텍스가있는 모든 lamd가 처리되면이 객체가 자동으로 삭제됩니다.
이 코드는 나머지 코드에 몇 가지 제한이 있으므로이 방법이 마음에 들지 않습니다. WinRT의 경우이 메서드는 어떤 스레드가이 개체를 삭제할지 제어하지 않으므로 결과적으로 UI 스레드 오류가 발생할 수 있습니다.
이것은 뮤텍스에만 해당되는 것은 아닙니다. 구성원이 아직 사용 중이면 개체를 삭제할 수 없습니다. – MSalters
@MSalters 동시성이 더 어렵습니다. 단일 스레드 코드의 경우 소멸자 또는 멤버 함수를 동시에 실행할 수 없습니다. 그리고 개체가 더 이상 필요하지 않을 때 개체가 삭제되므로 참조 된 개체 또는 RAII를 사용하여 항상 안전하게 삭제할 수 있습니다 ... 순환 참조 등은 예외입니다. – legokangpalla