user8646716
user8646716

Reputation:

Understanding Variable Accessibility in Threads

I'm trying to get a better understanding of accessing variables in threads. After doing a little bit of research, I found a lot of info about atomic, which works great! I've come to a stand-still, though, and would like some help moving forward.

Set Up:

Question:

Why can the threads with functions from the second class not read the information it inherited from the first class?

.

#include "stdafx.h"
#include "Windows.h"
#include <iostream>
#include <thread>
#include <atomic>

std::atomic<bool> timeToClose = false;

class first {
public:
    std::atomic<int> primary;
    void readFile() {
        primary = 1;
    }
    first() {
        primary = 0;
    }
};

class second: first {
public:
    void actionPrimary() {
        while (!timeToClose) {
            if (primary) {
                std::cout << "We ARE doing stuff here!\n";
                std::this_thread::sleep_for(std::chrono::milliseconds(1500));
            } else {
                std::cout << "We AREN'T doing stuff here!\n";
                std::this_thread::sleep_for(std::chrono::milliseconds(1500));
            }
        }
    }
};

int main() {
    first f;
    second s;
    f.readFile();
    std::thread threadActionPrimary([&s]() {
        s.actionPrimary();
    });
    while (!GetAsyncKeyState(VK_F1)) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    timeToClose = true;
    threadActionPrimary.join();
    std::cin.get();
}

Editing to bump :)

Upvotes: 1

Views: 79

Answers (1)

mksteve
mksteve

Reputation: 13073

When does items in thread a become visible to thread b.

This is related to cppreference : memory_order. A change is visible to a second thread.

  • thread A wrote to an atomic value (using std::atomic)
  • thread B read the atomic value (using std::atomic )

There are some more complex versions which relate to synchronization.

  • thread A writes some data.
  • thread A uses a mutex or writes to std::atomic << sync.
  • thread B uses mutex or reads from std::atomic
  • thread B can see all the memory changes from thread A up to the point it synchronized.

What is actually happening in this case, is instance data in a class variable.

class MyBase {
    public:
       int BaseValue;
       MyBase() : BaseValue(10);
       void setValue( int v ) {
           BaseValue = v;
       }
};

class MyDerived : public MyBase {
      MyDerived() {}
};

 MyBase base;
 base.setValue( 12 );
 MyDerived derived;
 // derived.BaseValue = 10;
 // base.BaseValue = 12;  <<<< There are 2 different instances of the member BaseValue.

Update

Each time you create a variable;

int i = 5;
int j = 10;

You create a new 'container' of things. If you want the two threads to communicate using one of the classes (second?) you need to create a single container, then the data should be visible.

However to get it to work correctly, you need to have some form of synchronization between the 2 threads.

int main() {
    second s;
    s.readFile();
    std::thread threadActionPrimary([&s]() { // this acts as a synchronization point, so the thread sees all the changes to s that happened before this line.
        s.actionPrimary();
    });
    while (!GetAsyncKeyState(VK_F1)) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    timeToClose = true;
    threadActionPrimary.join();
    std::cin.get();
}

Upvotes: 1

Related Questions