참고 사항 -이 빌드는 VS2008/VS2010 빌드 용입니다. 어떤 11 가지 구성도 사용할 수 없습니다.연동이 있습니까? C++
일부 게시자의 수신자가 있습니다. 내 게시자 구독자 포인터의 컨테이너가 있습니다. 내 void detach (ISubscriber *)에서는 구독자 목록을 잠그는 대신에 해당 구독자에게 더 좋은 단어가 없기 때문에 포인터를 "NULL"처리합니다.
//My container in the publisher. Inserts to not invalidate, removals only invalidate iterators pointing to the removed element, for this reason we NULL
Container<ISubscriber *> myContainer;
Now in the publisher...
void NotifySubscribers(){
foreach(subscriber in container){
if(subscriber)//This is my problem
subscriber->notify()
}
}
라인 3 - 포인터가 테스트되었고 유효한 개체를 가리키고 있습니다. 줄 4가 실행되기 전에 다른 스레드가 구독자를 NULL로 지정합니다. 줄 4 - 붐.
내 질문은 테스트 및 호출 원자 같은 일종의 연동 뭔가 사용할 수있는 방법이 있습니다.
소멸자의 레퍼런스 카운트 된 객체에 대해, 이런 일이 기준 카운터가 감소하고 오직 다음의 경우 0과 같지 제로 automically,에 대해 테스트되고, 여기서
RefCountObject::~RefCountObject(){
if(InterlockedDecrement(&m_count) == 0)
delete m_data;
}
작동 데이터는 해제된다.
포인터의 유효성을 기반으로 함수를 호출 할 때이 작업을 수행 할 수있는 방법이 있습니까?
편집 1 : 의견을 바탕으로 조금 명확히하고 답장을 보내 주셔서 감사드립니다. 게시자는 구독자의 "메모리 해제"에 대해 책임지지 않으므로 누출이 발생하지 않습니다. 알림 후에 게시자는 구독자를 삭제하여 컨테이너를 정리하는 루프를 진행합니다.
이제 구독자 자체에 대해서. 그들이 분리되면, 그들은 출판사의 말을 듣지 않게됩니다. 그들 자신은 정적 인 물체에서 살 것입니다 (이것은 우리가 요구하는 계약입니다). 왜? 우리는 통보하는 동안 자물쇠를 잡을 여유가 없기 때문에. 유일한 다른 옵션은 향후 버전 관리로 인해이 DLL에 통합되지 않기로 결정된 Share_Ptr을 사용하는 것이 었습니다.
shared_ptr로 작성된 손을 만들었지 만 리소스 관리 클래스에서 래핑되지 않은 객체에 대한 참조가 같은 함정에 빠지면 구독자가해야 할 "요구 사항"을 밀어 넣어야합니다. 해당 가입자의 구현 내에서 매달려있는 참조를 언급하지 않도록하십시오.
다시 말해서 구독자는 "릴리스"할 수 없으며 현재는이를 사용하는 모든 클라이언트가 정적 개체입니다. 우리는 미래를 바라보고있었습니다. 일부 사용자는 레거시 앱이므로 enabled_shared_from_this 등을 가져 오는 것이 쉽지 않습니다.
컨테이너를 걷는 동안 구독자를 삭제할 수 있다면 간단한 원자 테스트보다 더 높은 수준의 동기화/수명 관리가 필요합니다. 참조 카운터와 같습니다 (예 : 공유 포인터로 래핑 될 수 있음). *'notify()'가 실행되는 동안 * 삭제되는 객체로부터 보호해야합니다. –
ISubscriber 객체가 누출 될 수 있습니까? –
정말로 (뮤텍스를 사용하는 대신) 이것을 위해 원자가 실제로 필요합니까? Lockfree 구조는 좀 더 복잡한 구조에 특히 적합하기 때문에 악명이 높지 않으므로 흔히 노력할 가치가 없습니다. 이 경우에는 원자 테스트와 호출 (존재한다면)이 도움이되지 않을 것입니다. 왜냐하면 스레드가'notify' 안에있는 동안'subscriber'가 삭제되지 않는다고 보장 할 수 없기 때문입니다. – Grizzly