2009-09-10 4 views

ответ

4

есть не один, что я знаю, ближайший находится в резьбовых строительных блоках, имеет concurrent_unordered_map

В STL контейнеры позволяют concurrent read access from multiple threads до тех пор, пока вы не не делать одновременное изменение. Часто не нужно итерации при добавлении/удалении.

Руководство по обеспечению простого класса обертки является нормальным, я бы начал с чего-то вроде фрагмента кода ниже, защищая методы, которым вам действительно нужен одновременный доступ, а затем предоставляя «небезопасный» доступ к базе std :: set так люди могут выбрать другие методы, которые небезопасны. При необходимости вы можете защитить доступ, а также к приобретению итераторов и возврату их, но это сложно (тем не менее, чем писать собственный набор блокировки или собственный полностью синхронизированный набор).

Я работаю на параллельной библиотеке шаблонов поэтому я использую CRITICAL_SECTION из VS2010 бета повышения :: мьютекс работает слишком большой и RAII модель использования lock_guard почти необходимо независимо от того, как вы решите сделать это:

template <class T> 
class synchronized_set 
{ 
    //boost::mutex is good here too 
    critical_section cs; 
public: 
    typedef set<T> std_set_type; 
    set<T> unsafe_set; 
    bool try_insert(...) 
    { 
     //boost has a lock_guard 
     lock_guard<critical_section> guard(cs); 
    } 
}; 
0

Все, что я могу придумать, это использовать OpenMP для распараллеливания, вывести класс set из std и поместить оболочку вокруг каждой операции критического набора, которая объявляет эту операцию критической, используя #pragma omp критический.

+0

Я не думаю, что вы должны выходить из std-контейнеров. У них нет виртуальных деструкторов. В этом случае композиция была бы лучше. –

0

Qt класс QSet использует неявный обмен данными (копирование на семантику записи) и аналогичные методы с помощью std :: set, вы можете посмотреть его реализацию, Qt - lgpl.

1

Вы также можете ознакомиться с библиотекой ACE, в которой есть все контейнеры, защищенные потоками, которые вам когда-либо понадобится.

3

Почему бы не использовать общий мьютекс для защиты одновременного доступа? Обязательно используйте RAII для блокировки и разблокировки мьютекса:

{ 
    Mutex::Lock lock(mutex); 
    // std::set manipulation goes here 
} 

где Mutex :: Замок является классом, который блокирует мьютекс в конструкторе и отпирает его в деструкторе, и мьютекс объект мьютекса, который совместно по всем темам. Mutex - это только класс-оболочка, который скрывает любой конкретный примитив ОС, который вы используете.

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

0

Безопасность нитей и копирование на семантику написания - это не одно и то же. Это сказано ...

Если вы действительно используете семантику копирования на запись, то в библиотеках источников Adobe есть шаблон copy_on_write, который добавляет эту семантику к тому, с чем вы его создаете.

1

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