2011-04-11 82 views
0

以下代碼旨在返回尚未使用的最小非負整數。它從多個線程中調用。如果樣式看起來有點奇怪,那是因爲這個類只能用於僅包含標題的庫。多線程代碼:vector <bool>迭代器不兼容

class Unique 
{ 
public: 
    static unsigned int getIndex() 
    { 
     boost::unique_lock<boost::mutex> lock(get().mutex); 
     unsigned int index = 0; 
     while (index < get().valueInUse.size() && get().valueInUse[index]) 
      index++; 
     if (index == get().valueInUse.size()) get().valueInUse.push_back(true); 
     get().valueInUse[index] = true; 
     return index; 
    } 
    static void releaseIndex(unsigned int index) 
    { 
     boost::unique_lock<boost::mutex> lock(get().mutex); 
     get().valueInUse[index] = false; 
    } 
private: 
    static Unique &get() 
    { 
     static Unique s; 
     return s; 
    } 
    boost::mutex mutex; 
    std::vector<bool> valueInUse; 
}; 

調試時間問題偶爾出現與此代碼:

vector<bool> iterators incompatible 

堆棧跟蹤顯示發生在push_back()問題 - index爲零。 STL實現似乎認爲它插入vector<bool>的另一個實例的end()。使用Visual Studio 2010 Express。

任何想法?這段代碼是線程安全的,不是嗎?

+0

取而代之的是'矢量的'你可以使用'的std :: bitset'(http://www.cplusplus.com/reference/stl/bitset/)。 – yasouser 2011-04-11 15:26:57

+0

@yasouser雖然你需要在編譯時知道'bitset'的大小。 – 2011-04-11 15:27:40

+0

另請參閱此鏈接中標題爲「矢量特化:矢量」的小節:http://www.cplusplus.com/reference/stl/vector/。它專門討論了有關'vector yasouser 2011-04-11 15:34:58

回答

5

除非你能保證所創建的任何線程之前,它被稱爲一旦get功能當然不是線程安全的。而且,由於您使用get調用來獲取互斥鎖來保護其餘代碼,因此您肯定可以在那裏獲得一些意想不到的結果。

std::vector<bool>明確地專門用於每個布爾使用一個位,以便改變迭代結果(它使用我認爲的代理對象)。您是否嘗試過使用deque而不是vector作爲測試?

+1

另請考慮[boost](http://www.boost.org/)。[dynamic_bitset](http://www.boost.org/doc/libs/release/libs/dynamic_bitset/dynamic_bitset.html)。 – ildjarn 2011-04-11 15:37:27