gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 05:09:09 25 4
gpt4 key购买 nike

我试图更好地理解在线程中访问变量。在做了一些研究之后,我发现了很多关于 atomic 的信息,非常有用!不过,我已经停滞不前了,希望能得到一些帮助。

设置:

  • 我有两个类 - 一个类从文本文件中读取以获取上次启动的信息以及我每次启动所需的其他信息。这是一个单独的类,只是为了组织。读取的信息存储在原子变量中。

  • 另一个类具有我的所有功能。这包括它读取用于存储来自信息文件的信息的变量的地方。简单地说,这个类继承了第一个类保存那个信息文件的变量。

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

问题:

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

  • 我在线程创建之前很久就开始阅读了。也许是因为第二个类继承了原始变量(它们都初始化为 0),因为我在执行读取信息文件功能之前声明了它?
  • main 函数中的变量读取正常。

.

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

编辑凹凸 :)

最佳答案

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

这与 cppreference : memory_order 有关.第二个线程可以看到更改。

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

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

  • 线程 A 写入一些数据。
  • 线程 A 使用互斥锁或写入 std::atomic << sync.
  • 线程 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;

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

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

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

关于c++ - 了解线程中的变量可访问性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46337788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com