2012-02-29 2 views
1

У меня есть std::map<int, Object*> ObjectMap. Теперь мне нужно обновить карту, и обновление может произойти через несколько потоков. Таким образом, мы блокируем карту для обновлений. Но каждое обновление приводит к длительному вычислению и, следовательно, приводит к конфликту блокировки.Свернуть блокировку конкуренции C++ std :: map

Рассмотрим следующий сценарий.

class Order //Subject  
{ double _a, _b,_c; 
    std::vector<Customer* > _customers; 

    public:   
    void notify(int a, int b. int c) 
    {  
    //update all customers via for loop. assume a for loop and iterator i  
    _customers[i] ->updateCustomer(a,b,c) 
    }  

}; 
class SomeNetworkClass 
{ 
private: 
    std::map<int, Order*> _orders; 
public: 
    void updateOrder(int orderId, int a, int b, intc) 
    {  
    //lock the map 
     Order* order = _orders[orderId]; 
     order->notify(); 
    //release the lock 
    }  
} 

class Customer 
{ 
public: 
    void updateCustomer(int a,int b, int c) 
    { 
    //some lengthy function. just for this example. 
    //assume printing a, b and c multiple times 
    } 
} 

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

Спасибо Шив

+0

В коде вы показали, что вы не обновляя 'map' .. вы обновляете объект внутри карты .. сама карта не нуждается в блокировке только для этого. Вы можете синхронизировать метод 'update()' вместо блокировки карты. Конечно, вам нужно будет заблокировать карту, если один поток ее читает, а другое письмо к нему в то же время .. – Kashyap

+2

с проблемами многопоточности вы должны указать как можно большую проблему для решения. Некоторые вопросы: обновления только влияют на значения объектов или могут быть вставки/удаления с карты? Указывают ли указатели на другие объекты, хранящиеся на одной карте, или они создают связанный список? (если это список, могут быть добавлены объекты или удалены из списка?) Есть ли какие-либо отношения к объектам, которые могут быть использованы в ваших интересах (т. е. может ли более одного объекта указывать на один и тот же третий объект?) –

+0

@ thekashyap, Да, объект обновляется внутри карты, но перед тем, как я получаю доступ к объекту, карта заблокирована для более активных действий. Я думал, что это неявно. Извините за то, что я не понимаю. Но подумайте об обновлении в замке. –

ответ

0

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

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

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

Если между цепями существует другое разделение, тогда вероятность столкновения с тупиками велика.

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

class Object 
{ 
    Object * next; 
    Lock l; 
    Data d; 
    void update(Data d_new) 
    { 
    l.lock(); 
    d = d_new; 
    next->update(d_new); 
    l.unlock(); 
    } 
}; 
+0

Это не я ищу. Во-первых, AnotherObject - это другой класс. –

+0

Подумайте о ситуации как шаблон наблюдателя. Если объект хранится на карте и появляется обновление для объекта, мы должны обновить все возможные наблюдатели. Но в то же время исходная тематическая карта заблокирована, и ни один другой объект не может быть обновлен. Это приводит к серьезным нарушениям блокировки, когда обновление объекта очень часто. –

+0

Повторное использование объекта, просто чтобы мой код был коротким. По существу класс AnotherObject выглядит одинаково. Я могу изменить пример, если не ясно, что вам нужно делать. –

Смежные вопросы