c++ - 原子int集合的线程安全

标签 c++ multithreading c++11 stdatomic

我有以下类包装了一个原子整数 vector (std::vector< std::atomic_int >)

vector 在对象构造时正确调整大小并且不会改变大小。有用于获取、设置原子整数的常用访问器和修改器,但没有守卫/互斥量。

class MyList
{
    std::vector< std::atomic_int > collection_;

    static MyList myList_;

public:

    MyList() : collection_( MAX_SIZE, 0 ) {}

    static MyList& getMyList() { return myList_; }

    void set( size_t idx, int val )
    {
        collection_[idx].store( val, std::memory_order_relaxed );
    }

    int get( size_t idx ) const
    {
        return collection_[idx].load( std::memory_order_relaxed );
    }
};

我怀疑这可能不是线程安全的(它目前在单线程模型中运行没有问题),但希望能有任何意见。我想我主要关心的是未 protected 集合的线程安全性,而不是其中的元素。

最佳答案

首先,请务必注意您 can't have a vector of atomic ints没有一些恶作剧。

忽略这一点,根据 [container.requirements.dataraces],如果您仅访问 vector 以修改其内容,那么这似乎是线程安全的。

For purposes of avoiding data races (17.6.5.9), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at and, except in associative or unordered associative containers, operator[].

Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the con- tained object in different elements in the same container, excepting vector<bool>, are modified concurrently.

关于 operator[] 的措辞不是很清楚在这种情况下可能是非线程安全的,但实际上没有合理的实现应该违反这一点。

如果您想要更多保证,并且由于 vector 不会改变大小,您可以替换 vector<T>unique_ptr<T[]> ,在这种情况下是线程安全的。
此外,您应该使用保证安全同步和排序的内存顺序(除非您有充分的理由),而不是 memory_order_relaxed。 .根本不指定内存顺序,或使用 memory_order_acquire/memory_order_release对就是这样做的。
这导致以下非常相似的代码:

class MyList
{
    std::unique_ptr< std::atomic_int[] > collection_;

    static MyList myList_;

public:

    MyList() : collection_( new atomic_int[MAX_SIZE] ) {}

    static MyList& getMyList() { return myList_; }

    void set( size_t idx, int val )
    {
        collection_[idx].store( val, std::memory_order_release );
    }

    int get( size_t idx ) const
    {
        return collection_[idx].load( std::memory_order_acquire );
    }
};

关于c++ - 原子int集合的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32461926/

相关文章:

c++ - Ncurses:面板的 doupdate() 和 refresh() 之间的区别

c++ - Qt 没有用于 QProcess::finished() 信号的插槽

c++ - 在模板函数中自动将 const char[] 转换为 const char *

python - 使用 python 进行多线程?

c++ - C++11 中的线程池

c++ - 重载函数作为可变参数模板函数的参数

c++ - Windows XP 与 Vista/7 上的 MS Crypto API 行为

ios编程: Using threads to add multiple images to library

c++ - 使用数组作为元组成员 : Valid C++11 tuple declaration?

java - 有没有办法让多个线程顺序访问共享资源列表?