Howard 's는 이미 질문에 잘 대답했으며 Nicol은 호환되지 않는 많은 포인터 유형이 아닌 단일 표준 공유 포인터 유형을 갖는 이점에 대해 몇 가지 좋은 점을 지적했습니다.
위원회의 결정에 전적으로 동의하지만 특수한 경우에 비동기식 shared_ptr
유형 을 사용하는 것이 약간의 이점이 있다고 생각 하므로 주제를 몇 번 조사했습니다.
여러 스레드를 사용하지 않거나 여러 스레드를 사용하지만 스레드간에 포인터 소유권을 공유하지 않는 경우 원자 스마트 포인터는 과잉입니다.
프로그램이 여러 스레드를 사용하지 않을 때 GCC를 사용하면 shared_ptr은 refcount에 원자 연산을 사용하지 않습니다. 이것은 프로그램이 다중 스레드인지 (GNU / 리눅스에서는 프로그램이에 연결되는지 여부를 감지하여 간단하게 수행되는) 래퍼 함수를 통해 참조 횟수를 업데이트하고 libpthread.so
그에 따라 원자 적 또는 비원 자적 작업에 디스패치함으로써 수행됩니다.
몇 년 전에 GCC shared_ptr<T>
가 __shared_ptr<T, _LockPolicy>
기본 클래스 측면에서 구현 되었기 때문에 명시 적으로 사용하여 다중 스레드 코드에서도 단일 스레드 잠금 정책으로 기본 클래스를 사용할 수 있음을 깨달았습니다 __shared_ptr<T, __gnu_cxx::_S_single>
. 안타깝게도 이는 의도 된 사용 사례가 아니었기 때문에 GCC 4.9 이전에는 최적으로 작동하지 않았고 일부 작업은 여전히 래퍼 함수를 사용했기 때문에 명시 적으로 _S_single
정책을 요청 했음에도 불구하고 원자 작업으로 전달되었습니다 . http://gcc.gnu.org/ml/libstdc++/2007-10/msg00180.html 에서 포인트 (2) 참조자세한 내용과 다중 스레드 앱에서도 비 원자 구현을 사용할 수 있도록 GCC에 대한 패치를 참조하십시오. 나는 몇 년 동안 그 패치에 앉아 있었지만 마침내 GCC 4.9에 적용했습니다. 이렇게하면 이와 같은 별칭 템플릿을 사용하여 스레드로부터 안전하지 않지만 약간 더 빠른 공유 포인터 유형을 정의 할 수 있습니다.
template<typename T>
using shared_ptr_unsynchronized = std::__shared_ptr<T, __gnu_cxx::_S_single>;
이 유형은 상호 운용이 불가능하며 사용자가 추가로 제공 한 동기화 없이는 스레드간에 개체가 공유되지 않을 std::shared_ptr<T>
경우에만 사용하기에 안전 shared_ptr_unsynchronized
합니다.
물론 이것은 완전히 이식 할 수 없지만 때로는 괜찮습니다. 올바른 전 처리기 해킹을 사용하면가 shared_ptr_unsynchronized<T>
별칭 인 경우 다른 구현에서 코드가 여전히 잘 작동합니다 shared_ptr<T>
. GCC에서는 조금 더 빠릅니다.
4.9 이전에 GCC를 사용하는 경우 _Sp_counted_base<_S_single>
명시 적 전문화를 자신의 코드 에 추가하여이를 사용할 수 있습니다 (그리고 __shared_ptr<T, _S_single>
ODR 위반을 방지하기 위해 전문화를 포함하지 않고 인스턴스화 하지 않도록 보장 ). 이러한 std
유형의 특수화를 추가하는 것은 기술적으로 정의되지 않았지만 이 경우 GCC에 전문화를 추가하는 것과 자신의 코드에 추가하는 것 사이에는 차이가 없기 때문입니다.