了解线程中的变量可访问性

时间:2017-09-21 07:22:00

标签: c++ multithreading variables atomic

我正在努力更好地理解在线程中访问变量。在做了一些研究之后,我发现了很多关于fadeOut()的信息,这很有用!不过,我已经停滞不前了,希望能有所帮助。

设置:

  • 我有两个类 - 一个类从文本文件中读取以获取上次启动时的信息以及每次启动时需要的其他信息。这是一个单独的课程,仅供组织使用。信息读取存储在原子变量中。

  • 其他课程的全部我的职能。这包括读取用于存储来自信息文件的信息的变量的那些。简单地说,这个类继承了第一个包含该信息文件的变量。

  • main函数在代码的最开头一起创建了类对象,因为我需要类中的函数用于程序的其他部分。在初始设置(包括读取该信息文件)之后,它会从需要为程序的其余部分运行的第二类函数创建线程

问题:

为什么具有第二类函数的线程不能读取它从第一个类继承的信息?

  • 我在创建线程之前很早就读了。也许是因为第二个类继承了原始变量(都被初始化为0),因为我在读取信息文件函数之前声明了它?
  • 主函数中的变量读得很好。

atomic

编辑凹凸:)

1 个答案:

答案 0 :(得分:1)

  

线程a中的项目何时对线程b可见。

这与cppreference : memory_order有关。第二个帖子可以看到更改。

  • 线程A写入原子值(使用std::atomic
  • 线程B读取原子值(使用std::atomic

有一些更复杂的版本与同步有关。

  • 线程A写入一些数据。
  • 线程A使用互斥锁或写入std :: atomic<<同步。
  • 线程B使用互斥锁或从std :: atomic
  • 读取
  • 线程B可以看到从线程A到它同步点的所有内存更改。

在这种情况下实际发生的是类变量中的实例数据。

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.

更新

每次创建变量时;

int i = 5;
int j = 10;

您创建了一个新容器&#39;东西的。如果您希望两个线程使用其中一个类(second?)进行通信,则需要创建一个容器,然后数据应该是可见的。

但是要使其正常工作,您需要在两个线程之间进行某种形式的同步。

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