合并的“位”线程安全向量<bool>

时间:2019-07-19 14:14:56

标签: c++ multithreading vector boolean

据我所知:

  • vector<bool>涉及合并向量元素,即:V [i]占据单个位,而不是sizeof(bool)个字节。

  • “ Coalesced” vector<bool>不是“位”线程安全的,这意味着并发写入(即使写入不同位置)也不能保证没有数据争用(关于标准化“向量” vector<bool>被发现here)。

  • 这很好,但是没有:not是否涉及低级合并。

  • 即使使用vector<std::atomic_bool>也不是位线程安全(here)。

鉴于所有这些,这是我的问题:如何实现合并的std::bitset,以便对不同位置/位的并发写入是线程安全的?

2 个答案:

答案 0 :(得分:2)

您可以使用带有锁的常规并发模式。要考虑到节省空间可能是以运行时性能为代价的。

示例:

std::vector<bool> b(size);
std::mutex m;

//modify:
{
    std::lock_guard lock(m);
    b[0] = true;
}

// read
{
    std::lock_guard lock(m);
    std::cout << b[0];
}

如果要共享读取锁定,可以使用std::shared_mutex

答案 1 :(得分:0)

如果需要vector

@eerorika提供最简单的答案。但是,如果您想要高效的结构,则可以使用std::array<std::atomic<uint32_t>>。这样就可以避免完全锁定:

template<int size>
class FastBits
{
public:
    void set(unsigned int pos, bool value)
    {
        if (value)
        {
            mValues[pos / 32] |= (1 << (pos % 32));
        }
        else
        {
            mValues[pos / 32] &= ~(1 << (pos % 32));
        }
    }
    bool get(unsigned int pos)
    {
        return mValues[pos / 32] & (1 << (pos % 32));
    }

private:
    std::array<std::atomic<uint32_t>, (size + 31) / 32> mValues;
};

#include <iostream>
int main()
{
    constexpr int size = 10;
    FastBits<size> f;

    f.set(8, true);
    std::cout << f.get(8) << std::endl;

    f.set(8, false);
    std::cout << f.get(8) << std::endl;
}