Вопрос

Кто-нибудь знает, где я могу найти реализацию, которая оборачивает std::map и делает его потокобезопасным?Когда я говорю потокобезопасный, я имею в виду, что он предлагает только последовательный доступ к карте, по одному потоку за раз.В оптимальном случае эта карта должна использовать только конструкции стандартной библиотеки и/или повышения.

Это было полезно?

Решение

Не соответствует указанным критериям, но вы можете взглянуть на TBB контейнеры. Существует так называемый concurrent_hash_map , который позволяет нескольким потокам одновременно получать доступ к данным на карте. Есть некоторые детали, но все хорошо документировано и может дать вам представление о «параллельном контейнере». В зависимости от ваших потребностей это может быть совершенно неуместно ...

Другие советы

Как правило, классам коллекций не рекомендуется обеспечивать безопасность потоков, поскольку они не могут знать, как они используются. Вы будете гораздо лучше обслуживаться, если будете реализовывать свои собственные механизмы блокировки в конструкциях более высокого уровня, которые используют коллекции.

Повышение shared_mutex обеспечит лучший подход для нескольких читателей / писателей к переносу стандартной карты с учетом ваших ограничений. Я не знаю ни одного "предварительно построенного" реализации, которые объединяют эти два, так как задача, как правило, тривиальная.

Это зависит от реализации приложения.«Потокобезопасная» карта сделает отдельные вызовы карты потокобезопасными, но многие операции необходимо сделать потокобезопасными. через звонки.Приложение, использующее карту, должно связать с картой мьютекс и использовать этот мьютекс для координации доступа к ней.

Попытка создать потокобезопасные контейнеры была ошибкой в ​​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, это также сработает.

Здесь есть предложение (мной - бесстыдный плагин), которое оборачивает объекты (включая контейнеры STL ) для эффективного (без затрат) поточно-безопасного доступа:

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

  

Основная идея очень проста. Существует всего несколько классов-оболочек, используемых для принудительной блокировки чтения / записи и, в то же время, представления const (для чтения) или неконстантного (для чтения и записи) обернутого объекта.

     

Идея состоит в том, чтобы сделать невозможным неправильный доступ к ресурсу во время компиляции.

Код реализации можно найти здесь:

https://github.com/galik/GSL / блоб / блокируемые-объекты / включать / GSL / gsl_lockable

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top