1

디지털 신호 수집 시스템에서 데이터는 종종 한 스레드로 시스템의 관찰자에게 푸시됩니다. Wikipedia/Observer_pattern에서멀티 스레드 옵저버 용 디자인 패턴

예 :

foreach (IObserver observer in observers) 
    observer.Update(message); 

예컨대 예를 들어 GUI 쓰레드는 데이터 흐름을 멈추고, 관찰자 ​​연결을 끊고, 관찰자를 처분하기를 원한다.

데이터 소스를 중지하고 연결을 처분하기위한 센티널 값을 기다려야합니다. 하지만 시스템에 대기 시간이 더 많이 걸릴 수 있습니다.

물론 데이터 펌핑 스레드가 관찰자의 주소를 요청한 경우 파괴 된 개체에 메시지를 보내는 것으로 알 수 있습니다.

누군가이 상황을 대처하는 '공식적인'디자인 패턴을 만들었습니까? 그들은하지 않아도 될까요?

+0

나는 혼란 스럽다. 너는 무엇을 피하려고하는거야?하나의 스레드가 관찰자를 등록 취소하려고하지만 다른 스레드가 모든 관찰자를 반복하는 경우에 대해 이야기하고 있습니까? –

+0

"IObserver"를 구현하는 구체적인 클래스를 모르지만 "업데이트"가 "데이터 소스로 최신 정보를 가져 오기 위해해야 ​​할 일을 모두 수행"을 의미하는 경우, 폐기 된 객체의 올바른 동작은 다음과 같습니다. 조용히 아무것도하지 말라. 마지막으로 검사 된 이후에 구독 취소 요청을했는지 여부를 나타내는 플래그가 펌프 개체에있는 경우 구독자가 구독을 계속해야하는지 여부를 나타내는 각 관찰자와 연결된 개체가있는 경우 펌핑 스레드는 구독 취소를 위해 개체를 폴링 할 수 있습니다 필요할 때. – supercat

답변

2

데이터 소스가 항상 동시성의 안전 측면에 있도록하려면 항상 안전하게 사용할 수있는 포인터가 하나 이상 있어야합니다. 따라서 Observer 객체의 수명은 데이터 소스 이전에 끝나지 않아야합니다.

Observers 만 추가하면되지만 Observers는 제거하지 않으면됩니다. 각 관찰자가 핵심 구현 자체를 수행하지 않고 ObserverImpl 개체에이 작업을 위임하게 할 수 있습니다. 이 impl 개체에 대한 액세스를 잠급니다. 이것은 큰 문제가 아니며 ObserverImpl 객체를 사용하여 관찰자가 바쁘다면 잠시 동안 GUI 구독 취소자가 차단된다는 것을 의미합니다. GUI 응답 성이 문제가되는 경우, 취소 작업이 푸시 된 일종의 동시 작업 대기열 메커니즘을 사용할 수 있습니다. (Windows의 PostMessage와 같습니다)

가입을 취소 할 때는 핵심 구현을 더미 구현으로 바꾸면됩니다. 다시 한번이 조작은 자물쇠를 잡아야합니다. 이것은 실제로 데이터 소스를 기다리는 일부를 도입 할 것이지만, 단지 [잠금 포인터 스왑 잠금 해제]이므로 실시간 애플리케이션에 충분히 빠르다고 말할 수 있습니다.

더미를 포함하는 Observer 객체를 겹치지 않게하려면 일종의 부기를해야하지만, 이것은 목록에서 필요한 Observer 객체에 대한 포인터를 가진 객체와 같이 사소한 것으로 부술 수 있습니다 .

최적화 : 또한 Observer 자체만큼 실제 구현을 유지하는 경우 실제 잠금없이이 작업을 수행하고 InterlockedExchangePointer와 같은 것을 사용하여 포인터를 바꿀 수 있습니다. 최악의 시나리오 : 포인터가 스왑되는 동안 위임 호출이 진행 중입니다.> 모든 문제가 생기지 않고 위임을 계속할 수 있습니다. 다음 위임 호출은 새 구현 객체에 대한 호출입니다. (물론 새로운 스왑을 제외한)

0

모든 관찰자에게 데이터 소스가 종료 중이라는 것을 알리고 관찰자가 목록에서 자신을 삭제할 수 있음을 알리는 메시지를 보낼 수 있습니다.

설명에 대한 응답으로, subject-observer 패턴의 구현은 관찰자의 동적 추가/제거를 허용해야합니다. C#에서 이벤트 시스템은 관찰자가 event += observer을 사용하여 추가되고 event -= observer을 사용하여 제거되는 대상/관찰자 패턴입니다.

+0

사실, 데이터 소스는 계속 실행되고 있습니다 (예 : 거대한 설정 시간이 있기 때문에). 그리고 즉시 탈퇴하는 것이 좋습니다. – xtofl