在 C++ 中将(预定义的)原子值添加到向量
Posted
技术标签:
【中文标题】在 C++ 中将(预定义的)原子值添加到向量【英文标题】:Add (predefined) atomic values to vector in C++ 【发布时间】:2020-01-25 22:03:43 【问题描述】:我在 C++ 中使用多线程时遇到了一个问题。
我有一个类(称为 class_a_example),它在带有公共和受保护访问修饰符的头文件中定义。 class_a_example 取决于几个变量/结构。
在'protected'中我定义了 m_accessed 成员 - 向量由原子组成,当创建类的元素时,它还依赖于 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.h 和 class_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));
有什么方法(最好是简单的)来创建预定义的原子向量或为其添加值?
【问题讨论】:
m_accessed 变量似乎存在初始化问题。请查看:***.com/questions/29332897/… @Pankaj 谢谢,我试试这个变种 您的问题缺少minimal reproducible example。作为这里的新用户,也可以使用tour 并阅读How to Ask。也就是说,将互斥锁与原子混合可能是一个坏主意。你有什么具体原因吗? @UlrichEckhardt 我需要使用不在互斥锁下的原子,它们就像标志,报告何时需要打开互斥锁 【参考方案1】:std::atomic 没有复制构造函数。
使用
m_accessed.emplace_back();
m_accessed.back().store(0);
代替
m_accessed.emplace_back(std::atomic<uint32_t>(0));
【讨论】:
我试过你的变种,但不幸的是它和我得到的错误一样 虽然解释是正确的,但您的代码犯了这个错误。现在由您来提取和创建minimal reproducible example,以便我们为这次讨论找到一个共同的基础。 @UlrichEckhardt 我已经尝试过这段代码,但它并没有解决错误。我自己找到了解决方案,如果您有兴趣 - 您可以在下面查看***.com/a/59946282/12782346【参考方案2】:我找到了一个解决方案,可以用我想要使用的值来定义原子向量。问题解决了
// 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
;
在此操作之后,原子向量将成功创建并使用您想要的值进行定义。
【讨论】:
以上是关于在 C++ 中将(预定义的)原子值添加到向量的主要内容,如果未能解决你的问题,请参考以下文章