在 C++ 中向向量添加(预定义的)原子值

Add (predefined) atomic values to vector in C++

我在 C++ 中使用多线程时遇到了问题。

我有一个 class(称之为 class_a_example),它是在头文件中用 public 和受保护的访问修饰符定义的。 class_a_example依赖几个variables/structures.

在 'protected' 中我定义了 m_accessed 成员 - 向量由原子组成,当创建 class 的元素时,它还取决于 m_accessed,它需要在 m_accessed 中有预定义的值。就像这样:

// class_a_example_header.h

class class_a_example {
protected:
    std::vector<std::atomic<uint32_t>> m_accessed;
    std::vector<uint32_t> m_vars;
    std::mutex m_mtx;
    // some other structures

public:
    // some methods
    inline class_a_example(/*params*/, size_t c_count, /*params*/) : m_vars(c_count, 0), m_accessed(c_count, std::atomic<uint32_t>(0))
    {
        /* some actions */
    }
};

class_a_example_header.cpp中,在class_a_example的一种方法中,我需要与m_accessed进行交互(需要更改原子值):

// class_a_example_header.cpp

int32_t class_a_example::change_values(uint32_t thread_index)
{
    /* some actions */
    m_accessed[thread_index]++;
    /* some actions */
}

但是当我编译我的程序时,我得到一个错误要求(特别是在 m_accessed(c_count, std::atomic(0))):

inline class_a_example(/*params*/, size_t c_count, /*params*/) : m_vars(c_count, 0), m_accessed(c_count, std::atomic<uint32_t>(0))

错误是:

class_a_example.cpp:114:57:   required from here
/opt/rh/devtoolset-8/root/usr/include/c++/8/ext/new_allocator.h:136:4: error: use of deleted function ‘std::atomic<unsigned int>::atomic(const std::atomic<unsigned int>&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

之后我重写了class_a_example.hclass_a_example.cpp:

// class_a_example_header.h

class class_a_example {
protected:
    std::vector<std::atomic<uint32_t>> m_accessed;
    // ...

public:
    inline class_a_example(/*params*/, size_t c_count, /*params*/) : m_vars(c_count, 0), m_accessed()
    {
        // ...
    }
    // ...
};



// class_a_example_header.cpp

int32_t class_a_example::change_values(uint32_t thread_index)
{
    /* some actions */
    if (m_accessed.size() < m_vars.size())
        m_accessed.emplace_back(std::atomic<uint32_t>(0));

    m_accessed[thread_index]++;
    /* some actions */
}

但是一般错误是一样的,只是从这里开始:m_accessed.emplace_back(std::atomic<uint32_t>(0));

有没有办法(最好是简单的)创建预定义的原子向量或向其添加值?

std::atomic 没有复制构造函数。

使用

m_accessed.emplace_back();
m_accessed.back().store(0);

而不是

m_accessed.emplace_back(std::atomic<uint32_t>(0));

我找到了一个解决方案,可以用我想使用的值来定义原子向量。已经解决了问题

// class_a_example_header.h

class class_a_example {
protected:
    std::vector<std::atomic<uint32_t>> m_accessed;
    // some other structures

public:
    // some methods
    inline class_a_example(/*params*/, size_t c_count, /*params*/) : m_vars(c_count, 0), m_accessed(c_count)
    {
        for (auto it = m_accessed.begin(); it != m_accessed.end(); it++)
            std::atomic_init(&*it, 0u) //instead of 0u specify value you want to be in atomic
    }
};

在此操作之后,将成功创建原子向量并使用您想要的值进行定义。