2010-06-29 90 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. 矩陣上是否有讀取操作?如果是使用讀/寫鎖來提高性能。