kerzhy
kerzhy

Reputation: 9

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

I've faced a problem while working with multithreading in C++.

I have a class (call it class_a_example) which is defined in header file with public & protected access modifiers. class_a_example depends on several variables/structures.

In 'protected' I've defined m_accessed member - vector consists of atomics, and when an element of class is created, it also depends on m_accessed, which needs to have predefined values in m_accessed. Just like this:

// 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 */
    }
};

In class_a_example_header.cpp in one method of class_a_example I need to interact with m_accessed (need to change atomic values):

// class_a_example_header.cpp

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

But when I compile my program, I get an error required from (particularly in 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))

Error is:

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)...); }

After that I've rewritten class_a_example.h and 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 */
}

But error in general is the same, only it starts from here: m_accessed.emplace_back(std::atomic<uint32_t>(0));

Is there any way (preferably simple) to create predefined atomic vector or add values to it?

Upvotes: 0

Views: 225

Answers (2)

kerzhy
kerzhy

Reputation: 9

I've found a SOLUTION to define atomic vector with values I want to use. It has solved the problem

// 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
    }
};

After this actions atomic vector will be created successfully & defined with values you want.

Upvotes: 0

kusstas
kusstas

Reputation: 111

std::atomic hasn't copy constructor.

Use

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

Instead of

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

Upvotes: 1

Related Questions