2011-04-11 85 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