Domanda

Qualcuno sa dove posso trovare un impianto che avvolge un std :: map e lo rende thread sicuro? Quando dico thread thread sicuro intendo che offre solo l'accesso seriale alla mappa, un thread alla volta. In modo ottimale, questa mappa dovrebbe usare solo la libreria standard e / o i costrutti boost.

È stato utile?

Soluzione

Non soddisfa i criteri che hai specificato, ma puoi dare un'occhiata ai contenitori TBB . Esiste il cosiddetto concurrent_hash_map che consente a più thread di accedere contemporaneamente ai dati nella mappa. Ci sono alcuni dettagli, ma tutto è ben documentato e può darti un'idea del "contenitore simultaneo". A seconda delle tue esigenze, questo potrebbe essere del tutto inappropriato ...

Altri suggerimenti

In genere non è una buona idea per le classi di raccolta fornire sicurezza dei thread, perché non possono sapere come vengono utilizzate. Sarai molto meglio servito implementando i tuoi meccanismi di chiusura nei costrutti di livello superiore che usano le raccolte.

Il boost shared_mutex fornirebbe il miglior approccio a lettore multiplo / scrittore singolo per avvolgere una mappa standard dati i tuoi vincoli. Non conosco nessun "pre-costruito" implementazioni che sposano questi due poiché l'attività è generalmente banale.

Dipende dall'applicazione da implementare. Un "thread-safe" map renderebbe singole chiamate nella mappa thread-safe, ma molte operazioni devono essere rese thread-safe attraverso chiamate. L'applicazione che utilizza la mappa deve associare un mutex alla mappa e utilizzare tale mutex per coordinare gli accessi ad essa.

Cercare di creare contenitori thread-safe è stato un errore in Java, e sarebbe un errore in C ++.

Potresti dare un'occhiata a Libreria dei template thread sicuri

Prova questa libreria

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

È implementato in un moderno approccio basato su criteri c ++.

Ecco un taglio dal link per mostrare l'idea con il caso 'vector'

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.
}

Ho pensato a questo (che sono sicuro che può essere migliorato per prendere più di due argomenti):

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

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

Questo ti permette di fare:

// 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";
}

Se desideri usare uno std :: recursive_mutex e uno std :: set, anche questo funzionerebbe.

C'è una proposta qui (da me - spina spudorata) che avvolge gli oggetti (compresi i contenitori STL ) per un accesso sicuro (a costo zero) al thread:

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

  

L'idea di base è molto semplice. Esistono solo alcune classi wrapper utilizzate per imporre il blocco lettura / scrittura e, allo stesso tempo, presentare una vista const (per sola lettura) o non const (per lettura-scrittura) dell'oggetto spostato.

     

L'idea è di rendere impossibile il tempo di compilazione per accedere in modo errato a una risorsa condivisa tra thread.

Il codice di implementazione è disponibile qui:

https://github.com/galik/GSL / blob / serratura-oggetti / include / GSL / gsl_lockable

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top