2010-05-28 7 views
3

내 응용 프로그램 문제는 다음과 같습니다. -부스트 shared_ptr use_count 함수

큰 구조체 foo가 있습니다. 이 값은 크고 메모리 관리상의 이유로 데이터 처리가 완료되면 삭제하지 않으려 고합니다.

우리는 std::vector<boost::shared_ptr<foo>>.

내 질문에 저장되어 모든 처리가 완료되면 알고 관련이있다. 첫 번째 결정은 프로그램에 여러 실행 경로가 있고 어느 것이 마지막인지 예측할 수 없기 때문에 다른 응용 프로그램 코드가 구조에서 완전한 플래그를 표시하는 것을 원하지 않는다는 것입니다.

우리의 구현에서 일단 처리가 완료되면 벡터의 것을 제외한 boost::shared_ptr<foo>>의 모든 사본을 삭제합니다. 이것은 shared_ptr의 참조 카운터를 1로 떨어 뜨릴 것입니다. shared_ptr.use_count()를 사용하여 앱의 다른 모든 부분이 데이터로 처리되는 시점을 알 수있는 값이 1인지 확인하는 것이 실용적인가요?

내가 질문하는 또 다른 이유 중 하나는 공유 포인터 shared_ptr의 프로덕션 코드에 "use_count"를 사용하지 않는 것이 좋습니다.


편집 - 내가 말하지 않았다 우리가 새로운 foo를 필요로 할 때, 우리가 현재 사용하지 않는 foo를 찾고 foo는 포인터의 벡터를 스캔하고 다음 라운드에 대한 그 foo는 사용하는 것입니다 처리. 이것이 왜 reference counter가 1이라는 것이이 특정 foo 객체가 더 이상 사용되지 않도록하는 안전한 방법이라고 생각했기 때문입니다.

+0

코드가 멀티 스레드입니까? 이 경우 답변이 변경됩니다. – wheaties

+0

예, 3 ~ 6 개의 스레드가 데이터 작업 중 –

답변

4

내 즉각적인 반응 (그 이상은 아니지만)은 일종의 풀 할당 자의 효과를 얻으려고하는 것처럼 들리는 것입니다. operator newoperator delete을 오버로드하는 것이 더 효과적 일 수 있습니다. 이런 식으로 보통 shared_ptr을 사용할 수 있으며 지연시키려는 다른 작업은 해당 클래스의 operator delete에서 처리됩니다.

더 기본적인 질문이 남았습니다.이 목표를 달성하기 위해 정말로 무엇을하려고합니까? 메모리 관리 관점에서 보자면, 한 번에 많은 수의 객체에 대해 메모리를 할당하고, 전체 블록이 비어있는 경우 전체 블록을 한 번에 해제하는 것이 일반적입니다.이 순서로 무언가를하려한다면 shared_ptruse_count으로 게임을하는 것보다 newdelete을 오버로드하여 수행하는 것이 거의 확실합니다.

수정 : 귀하의 의견에 따라, 할 일이 옳은 것처럼 수업 소리에 newdelete을 오버로딩하십시오. 무엇보다도 기존 코드에 쉽게 통합 할 수 있습니다. 실제로, 당신은 종종 그것을 완전히 투명하게 할 수 있습니다.

할당 자에 대한 일반적인 아이디어는 편집 한 질문에서 설명한 것과 거의 같습니다. 자유로운 대상을 추적하기위한 구조 (비트 맵 및 연결된 목록 모두 공통)를 갖습니다. new은 객체를 할당 할 필요가있을 때 비트 벡터를 스캔하거나 자유 객체의 링크 된 목록의 머리를보고 그 주소를 반환 할 수 있습니다.

이것은 링크드리스트가 잘 작동 할 수있는 한 경우입니다. 무료 객체에 바로 링크를 저장하고 (사실상) 절대적으로 사용하지 않기 때문에 (일반적으로) 메모리 사용에 대해 걱정할 필요가 없습니다 목록을 보려는 경우, 객체를 할당해야 할 때 목록의 첫 번째 항목 만 잡을 수 있기 때문입니다. 당신은 자신의 새로운 아이디어에 대한 안드레이 Alexandrescu에 의해 그 이후 작은 객체 할당에 현대 C++ 디자인 장 (및 기사 또는 두 가지를보고 할 수 있습니다 있도록

것은 이런 종류의, 작은 물체 특히 일반적이다 그런 종류의 일을하는 방법). Boost :: pool 할당 자도 있는데, 일반적으로 적어도 어느 정도 유사합니다.

+0

내 문제를 아주 잘 요약했습니다. 우리는 이것을 다음 무료 객체를 얻을 수있는 객체 풀로 사용하려고합니다. 우리가하는 일이 무엇이든 우리는 새로운 앱뿐만 아니라 기존의 코드베이스에도 추가 할 수 있는지 살펴 봐야합니다. –

0

나는 shared_ptr의 use_count를 사용하여 트랙을 유지하려고 시도하는 대신 자신의 사용 카운터를 구현하는 것이 좋습니다. 이 방법을 사용하면 shared_ptr을 사용하는 것보다이 모든 것을 완벽하게 제어 할 수 있습니다. 권장하는대로 권장하지 않습니다. 또한 자신의 카운터를 미리 설정하여 처음에 구조의 복사본을 얻기 위해 초기화되는 모든 스레드에 의존하지 않고 데이터에서 작동해야하는 스레드 수를 허용 할 수 있습니다.

3

사용 횟수가 1인지 확인하려면 unique() 멤버 함수를 사용하십시오.

2

귀하의 응용 프로그램에는 Foo에 대한 모든 참조가 응용 프로그램에서 제거되는 방법이 있어야하며 그 방법은 use_count()을 검사하는 대신 사용해야합니다. 게다가 use_count()이 1보다 큰 경우 프로그램에서 어떤 작업을 수행합니까? 모든 참조를 제거하기 위해 shared_ptr의 기능에 의존해서는 안되며, 애플리케이션 아키텍처가 참조를 제거 할 수 있어야합니다. 벡터에서 제거하기 전에 최종 검사로서 assert(unique())을 사용하여 실제로 해제되는지 확인할 수 있습니다.

2

마지막 복사가 릴리스되었을 때 특정 기능을 호출하기 위해 shared_ptr의 사용자 정의 삭제 기능을 사용할 수 있다고 생각합니다. 그렇게하면 use_count을 전혀 사용하지 않을 것입니다.

shared_ptr이 뛰어난 처리만을 추적하도록 vectorshared_ptr 사본을 보유해야합니다.

부스트는 문서에 several examples of custom deleters입니다.