mercredi 5 février 2020

Updating an atomic variable with a non atomic and vice versa

I am updating an atomic variable size_t using from one thread and reading it from another. Following is the code:

Code:

// MyClass.hpp
#pragma once
#include <atomic>

class MyClass {
public:
    size_t GetVal() {
        return m_atomic_val;
    }

    void SetVal(const std::size_t val) {
        m_atomic_val = val;
    }

private:
    std::atomic<size_t> m_atomic_val{0};
};


// main.cpp
#include "MyClass.hpp"

#include <iostream>
#include <thread>

int main() {
    MyClass obj;
    obj.SetVal(4);

    std::thread my_thread = std::thread([&obj]{
       std::cout << "Thread started" << std::endl;
       std::this_thread::sleep_for(std::chrono::milliseconds(30));
        obj.SetVal(8);
    });

   std::this_thread::sleep_for(std::chrono::seconds(2));
   auto val = obj.GetVal();
   std::cout << "The value is: " << val << std::endl;
   my_thread.join();
}

Question:

  • But as you can see, I am updating m_atomic_val which is a std::atomic<size_t> with a size_t which is non atomic. Will this have bad repercussions? Is this illegal?

  • The return type of GetVal is size_t but its returning a std::atomic<size_t>. Is this wrong?

  • So, my primary quesion is that is mixing of atomic and non atomic variables allowed the way I am doing in the sample code?

  • This is only a simple example to demonstrate the question I have. What if there was one writer thread and one reader thread which are running concurrently and race conditions are very likely? Should I switch to using mutexes instead of atomics?

Environment:
My code runs on iOS, Android and macOS.

Aucun commentaire:

Enregistrer un commentaire