2010-08-16 5 views
1

C++에서 스레드 안전 클래스를 작성 중입니다. 모든 공용 메소드는 잠금 (비회원 스핀 잠금)을 사용합니다. 개인용 메소드는 lock-free입니다. 그래서 모든 것이 OK가되어야합니다 : 사용자가 공용 메소드를 호출하면 객체를 잠근 다음 개인 메소드를 통해 작업을 수행합니다. 하지만 공용 메서드가 다른 공용 메서드를 호출하면 데드 록이 발생합니다. 재귀 뮤텍스가 좋지 않다는 것을 읽었습니다. 디버깅하기가 어렵 기 때문입니다. 그래서 나는 C의 stdio 방식을 사용합니다 : public 메서드 Foo()는 객체를 잠그고 Foo_nolock()을 호출하여 전체 작업을 수행합니다. 그러나 나는 이러한 _nolock() 메서드가 마음에 들지 않습니다. 제 코드가 중복 된 것 같아요. 저는 아이디어가 있습니다. 잠금없는 클래스 BarNoLock과 BarNoLock의 인스턴스 인 단 하나의 멤버 만있는 스레드 안전 클래스 Bar를 만들겠습니다. 그리고 모든 Bar의 메서드는이 멤버를 잠그고 메서드를 호출합니다. 좋은 아이디어인가, 아니면 더 나은 패턴/관행이 있습니까? 감사. 업데이트 : 나는 여드름과 다리에 대해 알고 있습니다. OOP가 아닌 멀티 스레딩 패턴에 대해 묻습니다.컴포지션별로 클래스에 잠금 추가

답변

1

왜 재귀 뮤텍스가 나쁜 것으로 간주 될지 모르겠다.이 질문을 참조하십시오.

Recursive Lock (Mutex) vs Non-Recursive Lock (Mutex)

하지만 Win32에서 중요한 부분은 차단하지 않고 동일한 스레드에서 여러 항목을 지원하기 때문에 그것이 반드시 문제라고 생각하지 않습니다. doc :

스레드가 임계 구역을 소유하면 실행을 차단하지 않고 EnterCriticalSection 또는 TryEnterCriticalSection을 추가로 호출 할 수 있습니다. 이렇게하면 이미 소유하고있는 중요한 섹션을 기다리는 동안 스레드가 교착 상태를 일으키는 것을 방지 할 수 있습니다. 스레드가 소유권을 해제하려면 스레드는 임계 영역에 진입 할 때마다 LeaveCriticalSection을 한 번만 호출해야합니다. 대기중인 스레드가 중요한 섹션의 소유권을 획득하는 순서에 대한 보장은 없습니다.

그래서 자신이 교착 상태에 빠졌을 때 뭔가 다른 것을하고 있었습니까? 이상한 함수 호출 구문과 동일한 스레드에서 동일한 뮤텍스에 자신을 교착 상태로 처리하지 않으려면 수행해야 할 작업이 아닙니다.

+0

글쎄요, CS가 재귀 적입니다. 내 응용 프로그램은 실제로 이론적으로 만 실제 잠금 상태가 아닙니다. 하지만 재귀 잠금을 사용하고 싶지 않습니다. – f0b0s

+0

재귀 적 잠금에 맞춰 죽은 사람이라면 합리적이라고 생각하는 것을 제안합니다. 내가 말하고자하는 다른 것 중 하나는 객체의 하나의 공용 함수가 다른 객체라고 불렀을 때 원래 설계에서 문제가 발생했다는 것입니다. 확실한 해결 방법은 그렇게하지 않는 것입니다. 공유해야 할 기능을 공유 할 때마다 비공개 비공개 방법으로 공유해야합니다. 그런 다음 각 공용 메소드는 잠금을 풀고 사용되는 개인 메소드가 잠금을 해제하지 않습니다. – bshields

+0

bshields : 그렇다면 공개 메서드의 모든 기능을 lock-free private metods에 넣으라고 조언합니다. Foo() -> Foo_nolock()? 그 원래 디자인 – f0b0s

1

Bridge Pattern을 재발견 한 것으로 보입니다. 순서대로 완벽하게 들립니다.

+0

그게 내가 말한거야 - 교량이나 여드름. 예. OOP가 아닌 다중 쓰레딩 관용구에 대해 물어 보았습니다. – f0b0s

관련 문제