2010-06-29 96 views
4

我的问题是,我有块矩阵由多个线程更新。 多个线程可能一次更新不相交的块,但通常可能存在竞争条件。现在矩阵使用单锁锁定。boost线程互斥阵列

问题是,是否有可能(如果是,怎么样?) 实现一个有效的锁定阵列,以便一次只能锁定矩阵的某些部分。

所讨论的矩阵可以变得相当大,按照50^2个块的顺序。我最初的猜测是使用动态分配互斥体的向量/地图。

这是好的方法吗? 是否更好地使用多个条件变量? 有没有更好的方法?

谢谢

+0

您是否总是在您的程序中使用相同的矩阵?或者它是一个矩阵序列(如视频处理)? – 2010-06-29 20:50:58

+0

@Emil它是相同的矩阵 – Anycorn 2010-06-29 20:57:36

回答

5

使用一个锁。但不是用它来保护整个矩阵,而是使用它来保护std::set(或boost::unordered_set),它说明哪些块被“锁定”。

就是这样。

class Block; 

class Lock_block 
{ 
public: 
    Lock_block(Block& block) : m_block(&block) 
    { 
     boost::unique_lock<boost::mutex> lock(s_mutex); 
     while(s_locked.find(m_block) != s_locked.end()) 
     { 
     s_cond.wait(lock); 
     } 
     bool success = s_locked.insert(m_block).second; 
     assert(success); 
    } 

    ~Lock_block() 
    { 
     boost::lock_guard<boost::mutex> lock(s_mutex); 
     std::size_t removed = s_locked.erase(m_block); 
     assert(removed == 1); 
     s_cond.notify_all(); 
    } 
private: 
    Block* m_block; 

    static boost::mutex s_mutex; 
    static boost::condition s_cond; 
    static std::set<Block*> s_locked; 
}; 
+0

这确实比较简单。 谢谢 – Anycorn 2010-06-29 21:26:16

1

这可能是几种方法,你可以使用:

  1. 预分配数组,如果CriticalSection的/互斥(2500是没有那么多),并使用块索引作为锁索引收集块访问;在更新块之前锁定你想要改变的所有块;做更新;开锁;

  2. 如果计算时间显着延长,则锁定/解锁,然后在线程上下文中复制该块的内容并在该时间内保持块被解锁;在更新块之前再次锁定它并确保它没有被另一个线程更新(如果它与此相关);如果它被另一个线程更新,则重复操作;

  3. 如果块内容的大小很小,使用原子数据交换来更新块内容,不需要锁;只是不确定是否使用来自一个块的数据来计算另一个块的数据,在这种情况下,需要锁定所有更新的块;

  4. 矩阵上是否有读取操作?如果是使用读/写锁来提高性能。