문제

누구든지 내가 랩핑하는 구식을 찾을 수있는 곳을 아는 사람이 있습니까? std::map 그리고 스레드를 안전하게 만들까요? 스레드 안전하다고 말할 때는 맵에 대한 직렬 액세스, 한 번에 하나의 스레드 만 제공한다는 것을 의미합니다. 최적 으로이 맵은 표준 라이브러리 및 / 또는 부스트 구성 만 사용해야합니다.

도움이 되었습니까?

해결책

지정한 기준을 충족하지는 않지만 TBB 컨테이너. 소위 호출이 있습니다 concurrent_hash_map 이를 통해 여러 스레드가 맵의 데이터에 동시에 액세스 할 수 있습니다. 몇 가지 세부 사항이 있지만 모든 것이 잘 문서화되어 있으며 "동시 컨테이너"에 대한 아이디어를 줄 수 있습니다. 귀하의 요구에 따라 이것은 완전히 부적절 할 수 있습니다 ...

다른 팁

일반적으로 컬렉션 클래스가 스레드 안전성을 제공하는 것은 좋은 아이디어가 아닙니다. 스레드 안전성을 제공하는 방법을 알 수 없기 때문입니다. 컬렉션을 사용하는 더 높은 수준의 구성에서 자신의 잠금 메카인주의를 구현함으로써 훨씬 더 나은 서비스를 제공 할 것입니다.

Boost Shared_Mutex는 제약 조건이 주어지면 표준 맵을 포장하기위한 최고의 다중 독자/단일 작가 접근 방식을 제공합니다. 작업은 일반적으로 사소한이기 때문에이 두 가지와 결혼하는 "사전 구축 된"구현을 모릅니다.

이것은 구현하기위한 응용 프로그램에 달려 있습니다. "Thread-Safe"맵은 개별 호출을 맵으로 연결시킬 것이지만 많은 작업이 스레드-안전을 만들어야합니다. 가로질러 전화. 맵을 사용하는 응용 프로그램은 뮤트를 맵과 연결하고 해당 뮤텍스를 사용하여 액세스를 조정해야합니다.

스레드 안전 컨테이너를 만들려고 시도하는 것은 Java에서 실수였으며 C ++의 실수가 될 것입니다.

당신은 볼 수 있습니다 스레드 안전 템플릿 라이브러리

이 라이브러리를 사용해보십시오

http://www.codeproject.com/kb/threads/lwsync.aspx

현대 C ++ 정책 기반 접근법으로 구현됩니다.

다음은 '벡터'케이스와 함께 아이디어를 보여주기 위해 링크에서 컷입니다.

typedef lwsync::critical_resource<std::vector<int> > sync_vector_t;
sync_vector_t vec;

// some thread:
{
   // Critical resource can be naturally used with STL containers.
   sync_vector_t::const_accessor vec_access = vec.const_access();
   for(std::vector<int>::const_iterator where = vec_access->begin();
         where != vec_access->end();
         ++where;
        )
   std::cout << *where << std::endl;
}

sync_vector_t::accessor some_vector_action()
{
   sync_vector_t::accessor vec_access = vec.access();
   vec_access->push_back(10);
   return vec_access;
   // Access is escalated from within a some_vector_action() scope
   // So that one can make some other action with vector before it becomes
   // unlocked.
}

{
   sync_vector_t::accessor vec_access = some_vector_action();
   vec_access->push_back(20);
   // Elements 10 and 20 will be placed in vector sequentially.
   // Any other action with vector cannot be processed between those two
   // push_back's.
}

나는 이것을 생각해 냈다 (나는 두 가지 이상의 논쟁을 취하기 위해 개선 될 수 있다고 확신한다).

template<class T1, class T2>
class combine : public T1, public T2
{
public:

    /// We always need a virtual destructor.
    virtual ~combine() { }
};

이것은 당신이 할 수 있습니다 :

// Combine an std::mutex and std::map<std::string, std::string> into
// a single instance.
combine<std::mutex, std::map<std::string, std::string>> lockableMap;

// Lock the map within scope to modify the map in a thread-safe way.
{
    // Lock the map.
    std::lock_guard<std::mutex> locked(lockableMap);

    // Modify the map.
    lockableMap["Person 1"] = "Jack";
    lockableMap["Person 2"] = "Jill";
}

std :: recursive_mutex와 std :: set을 사용하려면 작동합니다.

여기에 (나이 - Shameless Plug)가 물체를 감싸는 제안이 있습니다 ( STL 컨테이너) 효율적인 (제로 비용) 스레드 안전 액세스 :

https://github.com/isocpp/cpcoreguidelines/issues/924

기본 아이디어는 매우 간단합니다. 읽기/쓰기 잠금을 시행하는 데 사용되는 몇 가지 래퍼 클래스가 있으며 동시에 래핑 된 객체의 const (읽기 전용) 또는 비정규 (읽기 쓰기)보기를 나타냅니다.

아이디어는 스레드간에 공유되는 리소스에 부적절하게 액세스 할 수 있도록 컴파일 타임을 불가능하게 만드는 것입니다.

구현 코드는 여기에서 찾을 수 있습니다.

https://github.com/galik/gsl/blob/lockable-objects/include/gsl/gsl_lockable

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top