2013-01-05 2 views
4

드물게 수정되지만 빠른 읽기 액세스가 필요한 힙에 할당하는 데이터 구조가 있습니다. 하나의 예제는 많은 스레드가 읽기 전용 방식으로 매우 자주 액세스하는 힙에 할당 된 구조체입니다. 주기적으로이 구조체를 다시 작성해야하고 경합을 피하기 위해 나는 auto_ptr을 사용하는 것이 안전하다면 기본적으로 참조를 획득 한 스레드가 처리가 끝날 때까지 처리를 허용하지만 작성자는 구조체, 그것을 다시 작성하고 신속하게 구조체의 새로운 auto_ptr 인스턴스와 포인터를 교환하십시오.다중 스레드 환경에서 잠금없이 객체를 교환하려면 auto_ptr을 사용하는 것이 안전합니까?

나는이 아이디어를 Java에서 CopyOnWriteArrayList에서 얻었고 C++에서 비슷한 성능을 내기를 희망했다.

답변

1

reset()을 사용하여 auto_ptr을 즉시 재 할당 할 수 있습니다. 이전에 가리킨 객체 인스턴스를 삭제합니다.

그러나 auto_ptr은 unique_ptr에 의해 사용되지 않으며 swap() 함수가 있습니다.이 함수는 사용자가 찾고있는 것으로 고정되어있는 것처럼 보입니다.

이 클래스는 이 아니고 스레드 안전성이입니다.

8

std::auto_ptr은 제안 할 때 reset()과 같은 비 const 멤버를 호출 할 때 스레드 안전성을 보장하지 않습니다. 또한 auto_ptr 대체품으로 생각해야 할 std::unique_ptrauto_ptr과 같이 사용하지 않는 것이 좋습니다.

std::shared_ptr은 스레드 안전 보장을 제공합니다. 당신은 일반적으로 shared_ptr으로 보장 무엇

는 참조 카운트가 아무도 현재 해당의 shared_ptr 수정되지 않도록 제공하는 shared_ptr의 사본을 만들 때 데이터 경주에서 안전하다는 것을 의미 원자 방식으로 조작하는 것이 매우 순간.

shared_ptr에 대해 다음 유스 케이스를 고려하십시오. 현재 shared_ptr<string> sharedString; (이)가 std::string의 인스턴스를 가리키고 있습니다. 많은 스레드가 get()을 호출하여 문자열에 대한 포인터를 검색하는 것이 안전합니다. 그들은 공유 포인터가 가리키는 포인터를 아무도 변경하지 않는다면 shared_ptr<string> myString = sharedString;처럼 자신의 공유 포인터를 만들 수도 있습니다.

이제 예제로 돌아가 경쟁 조건을 수정하십시오. 전역 공유 포인터가 가리키는 것을 변경할 시간이되면 스레드가 복사본을 만들 수 있습니다. 이는 일관성없는 상태로 복사본을 남길 수 있기 때문에 문제입니다. 따라서 우리는 그것을 원자 적으로 변경하고 복사해야합니다. atomic_load, atomic_storeatomic_exchange : 다행히 우리를 위해

, shared_ptr는 C++ 11 원자 작업의 전문을 제공합니다.

shared_ptr 사본을 만들 때는 atomic_load을 사용하고 shared_ptr을 업데이트하는 경우 atomic_store을 사용하십시오.

이렇게하는 것은 두 가지 이유로 중요합니다.

  1. atomic_ * 연산은 공유 포인터의 복사본을 만들 수있는 스레드로부터 안전한 방법을 제공합니다.
  2. 복사본을 만드는 것은 글로벌 공유 포인터가 변경 될 때 복사본이 이전 문자열을 여전히 가리 키므로 코드가 예상대로 작동하지 않을 때 변경할 데이터를 걱정할 필요가 없습니다.

이제 shared_ptr에서 스레드로부터 안전한 작업을 사용하면 스레드 유형이 가리키는 유형에 대한 스레드 안전성이 제공되지 않는다는 점에 유의해야합니다. 가리키는 객체가 스레드로부터 안전하게 사용되는 것은 항상주의해야합니다.

+0

'shared_ptr'에 대한 스레드 안전 보장에 대해 설명하는 링크가 있습니까? – JaredC

+0

예! 스레드 안전성은 C++ 표준에서'[util.smartptr.shared.atomic]'제목 아래에 설명되어 있습니다. 그리고 여기에 [제안] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2632.html)에 대한 링크가 있는데,이 기능은 사용법을 설명하고 일부 기능을 제공합니다. 암호. –

+0

gcc wo/C++ 11 확장의 비슷한 메커니즘에 대한 아이디어가 있습니까? C++ 11의 atomic_ * 기능 대신 gcc 내장 함수를 사용할 수 있습니까? – stgtscc

관련 문제