2015-06-09 13 views
0

我正在用Linux中的c/C++开发一些程序。我的问题是:LInux/C++,如何同时保护两个数据结构?

  1. 我有一个名为库中的上层阶级,其内部也有它使用unordered_map的数据结构和手持订单,其中有2个的std ::在侧列表中的OrderMap。
  2. OrderMap和OrderBook都存储Order *作为元素,它们共享一个Order对象,该对象在堆上分配。所以无论是OrderBook还是OrderMap都会修改其中的顺序。
  3. 我有两个线程会对它们执行读写操作。 2个线程可以插入/修改/检索(读取)/删除元素。

我的问题是:如何保护这个“Vault”的大结构?我实际上可以保护地图或列表,但我不知道如何同时保护它们。

有人给我一些想法吗?

+1

OT:我不能是唯一一个在使用'unordered_map'实现OrderMap时看到讽刺意味的事情。 – WhozCraig

+0

我只想用一个额外的锁来保护结构。 – Voo

+1

@WhozCraig:好吧,因为它是一个无序Order对象的映射,我不太明白这个讽刺(除了与OrderedMap明显的名字相似之外)。 – JBarberU

回答

1

在访问任何一个之前添加一个互斥锁并锁定它。

让他们私人的,所以你知道的访问是通过你的成员函数(其中有适当的锁)制成

考虑使用的std :: shared_ptr的,而不是令*

1

我不认为我已经曾见过订单簿的多线程用法。我真的认为你最好只在一个线程中使用它。

但是,为了回到你的问题,我会假设你无论出于何种原因都停留在2线程中。
该数据结构太复杂,无法锁定。因此,这些是我可以看到的多线程选项:
1.如果您为这两个线程使用一个单个 Vault实例,则必须锁定它。我假设你不在乎烧一些cpu时间,所以我强烈建议你使用自旋锁,而不是互斥锁。
2.如果您可以允许拥有2个Vault实例,这可以改善事情,因为每个线程都可以保留自己的私有实例,并使用其他方式与其他线程交换修改:无锁队列或其他方法。
3.如果您的书的拷贝速度足够快,您可以拥有一个中央保管库指针,在每次更新时创建一个副本,或者在该中央指针上创建一组CAS更新,然后重新使用旧的不必每次分配。每个线程最终会有一个备用实例。像这样:

Vault* old_ptr = centralVault; 
Vault* new_ptr = cachedVault ? cachedVault : new Vault; 
do { 
    *new_ptr = *old_ptr; 
    makeChanges(new_ptr); 
} 
while(!cas(&centralVault, old_ptr, new_ptr)); 
cachedVault = old_ptr; 
相关问题