2009-01-08 5 views
13

Boost.Asio와 많이 놀았습니다. 오늘날의 멀티 코어 시스템에서 성능을 끌어낼 수있는 환상적인 방법을 제공하기 때문에 도서관을 좋아합니다.Boost.Asio를 사용할 때 유효한 개체 수명을 보장하는 가장 좋은 방법은 무엇입니까?

질문 몇 번이나 물어 보았습니다. Asio와 비동기 호출을 할 때 개체 수명/소유권에 관해서는 가치가 있다고 생각했습니다.

반복적으로 문제가 발생한다는 것은 종종 비동기 콜백이 보류중인 개체를 "만료"해야한다는 것입니다. 콜백이 호출되기 전에 해당 객체가 범위를 벗어나면 필연적으로 쾅하는 일이 발생합니다.

대부분의 asio 기반 클래스의 기본 클래스로 boost::enable_shared_from_this 템플릿을 사용했습니다. 이 작업은 정상적으로 처리되지만 약간 부담 스럽습니다. 일반적으로 이것은 생성자를 보호하고 클래스에 factory 메소드를 추가하여 모든 인스턴스가 shared_ptr 내에 생성되도록합니다.

다른 사람들이이 문제를 어떻게 해결했는지 알고 싶었습니다. 이게 최선의 방법일까요? 아니면 내 Asio있어. 완전히 틀렸어?

토론 ... :)

답변

1

그런 종류의 것이 Asio에 국한되지 않습니다. 나는 최근에 Boost :: Thread를 사용하여 스레드 풀 클래스를 작성했는데, 그 스레드는 동일한 문제를 가지고 있었다. 스레드는 일반 포인터를 사용하여 다음에해야 할 작업을보기 위해 스레드 풀 클래스를 호출했다. 스레드 스레드 풀 클래스가 여전히 실행중인 자식 스레드와 함께 파괴되면 프로그램이 중단됩니다. 스레드 풀 소멸자의 각 스레드에서 interrupt을 호출 한 다음 소멸자를 반환하기 전에 모든 스레드가 종료 될 때까지 기다리는 방법으로 처리했습니다.

공유 포인터 솔루션을 이해한다면 동일한 일반적인 작업을 수행하는 것 같습니다. 더 이상 필요하지 않을 때까지는 항목을 삭제할 수 없습니다. 심미적으로 만족스러운 솔루션입니다. 나는 이런 종류의 문제에 대한 더 좋은 대답을 보지 못했다.

+0

재미있는 시나리오는 다음과 같습니다. 제 동료 (Alan이라고 알려짐)가 당신과 같은 일을하고 있었고 나와 같은 문제 였기 때문에 "해결책"을 언급했습니다. 나는 아직도 그것에 만족하지 않습니다 : 나는 결정론의 부족을 좋아하지 않지만, 그렇다면 그것은 스레딩입니다. – jkp

2

boost::enable_shared_from_this을 사용하면 꽤 많은 방법입니다. 또한 남아있는 유일한 참조 인 경우 객체를 보존하지 않아야하는 객체에 대한 참조가 필요한 경우 boost::weak_ptr을 사용하십시오.

weak_ptr의 좋은 예 : boost::asio을 사용하는 소켓 클래스에 enable_shared_from_this을 사용합니다. boost::asio 프레임 워크는 읽기 및 쓰기 처리기를 통해 개체에 대한 지속적인 참조를 저장하는 유일한 개체입니다. 따라서 소켓의 소멸자가 호출 될 때 소켓이 닫혔다는 것을 알았고 핸들러에서 닫힌 소켓을 정리할 수 있습니다. 소켓을 사용하는 응용 프로그램은 weak_ptr 참조를 가지고 있으며 소켓에 대한 작업 (일반적으로 쓰기 작업)을 원할 때 shared_ptr으로 승격됩니다.ソケット의 클로즈 처리기가 보통 weak_ptr 참조를 적절하게 정리하기 전에 소켓이 사라진 경우 실패를 확인할 수 있습니다.