【问题标题】:Add (predefined) atomic values to vector in C++在 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.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&lt;uint32_t&gt;(0));

有什么方法(最好是简单的)来创建预定义的原子向量或为其添加值?

【问题讨论】:

  • m_accessed 变量似乎存在初始化问题。请查看:stackoverflow.com/questions/29332897/…
  • @Pankaj 谢谢,我试试这个变种
  • 您的问题缺少minimal reproducible example。作为这里的新用户,也可以使用tour 并阅读How to Ask。也就是说,将互斥锁与原子混合可能是一个坏主意。你有什么具体原因吗?
  • @UlrichEckhardt 我需要使用不在互斥锁下的原子,它们就像标志,报告何时需要打开互斥锁

标签: c++ multithreading vector atomic


【解决方案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 我已经尝试过这段代码,但它并没有解决错误。我自己找到了解决方案,如果您有兴趣 - 您可以在下面查看stackoverflow.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
    }
};

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 2020-10-15
    相关资源
    最近更新 更多