会读取的种族条件会同时改变读取和书写的数据
Will a read-write race condition alter the data read and written simultaneously?
例如,如果我有以下代码:
SomeType obj;
void GUIThread()
{
...
while (true)
// Read and print the content of obj
...
}
void workerThread()
{
...
// Do some calculation and write the result into obj
...
}
出于绩效原因,我无力使用MUTEX或obj
上的任何内容,并且我不需要GUIThread
打印的精确性(obj
存储workerThread
的运行计算结果,可以将其视为"运行总计"。GUIThread
需要做的只是显示在workerThread
中完成的计算的近似进度)。我要确保的是,GUIThread
和workerThread
之间的读写竞赛条件不会改变obj
中存储的数据,并且不会导致程序崩溃。真的吗?
P.S。SomeType
包含内置整数类型和std::bitset<T>
,但只有前者会同时访问。bitset
仍然不受GUIThread
的影响。
P.P.S。也许这与主题相比有点不合时间...但是我认为我可以将运行结果存储在workerThread
中的缓存中,并且仅在每个相对较长的时间段内更新实际受保护的结果(无论是原子能或静音锁定还是其他)。为了实现这一目标,我需要确保以下代码按预期工作:
struct SomeOtherType
{
int a, b, c, d; // And other primitive types
}
std::atomic<SomeOtherType> data; // Will this work?
我想知道这是否可以保护SomeOtherType
,我认为可以保护它,因为SomeOtherType
中只有原始类型。
您在说的是"我正在编写不确定行为的代码。它会做我想做的事吗?"。唯一的答案是没有人知道,除了编译器作家。
似乎您的代码可能会做您想要的事情,因为这似乎是实现编译器的最简单方法。但是它很可能会决定循环之外的任何内容都可以写入该变量,因为如果这样做,那将是一场数据竞赛,因此,标准对其将要做什么没有说明该程序的一部分由于无法更改并重复使用该内存以存储另一个指针的值,因此您的其他线程将为NULL设置完全无连接的值,并在一个小时后将您的程序崩溃。当然,这不太可能,但我可以看到它可能是如何发生的。
不确定的行为就是 - 未定义。从字面上看,它可以做任何事情。有些事情显然比其他事情更有可能,但是您真的想冒险格式化用户的磁盘,因为您认为"未定义"不适用于您的程序,无论风险似乎有多小吗?
据我了解,您的结构看起来像
struct Data {
int one;
int two;
std::bitset<SomeType> three;
}
如果您不想使用任何类型的锁,则可以尝试将共享指针交换为此结构。检查您的编译器是否支持它,这是一个新功能。
std::shared_ptr<Data> dataPointer;
void GUIThread()
{
...
while (true) {
auto ptr = std::atomic_load(&dataPointer);
// Read and print the content of *ptr
...
}
void workerThread()
{
...
// Do some calculation
auto newPtr = std::make_shared<Data>();
// make the new result visible to the gui thread
std::atomic_store(&dataPointer, newPtr);
}
严重取决于共享数据类型。复杂的数据类型可能发生的事情是,在写操作中,对象短暂地变为无效(例如,分配新的内部缓冲区)。
对于简单的数据类型,例如整数,浮点等。代码在大多数情况下不会崩溃,但请保证!。应将其声明为volatile
,以避免编译器缓存在寄存器中。强迫记忆障碍将提高您的结果准确性。
如果您只是在检查布尔国旗或类似的东西,则可以逃脱。
如果OBJ是线程安全的,那么您也可以。
我的建议,如有疑问,请使用诸如Spinlocks之类的低顶锁。
- 如何在ros2中从rosbag2读取数据
- OpenCV 和从 OutputArrays 或 (Mat) 读取数据
- 使用C++从磁卡读卡器MT188读取数据
- HDF5 简单读取数据集失败
- 嵌套结构,从由空行分隔的文件中读取数据
- 不要从输入队列套接字读取数据
- 从文件中读取数据,操作员>>
- 如何从excel文件中读取数据并存储到变量中?
- C++:从文件中读取x y数据会产生无限循环吗
- 无法通过FT232RL读取数据
- 如何从QNetworkReply读取数据?
- C++ 逐行从文件(包含空格)读取数据
- 通过显示一行星号来创建条形图,该条形图将读取数据的输入文件
- 我们可以从 TXT 文件中读取数据并使用 C 和 C++ 将其保存到 SQL 数据库吗?
- 从多个 tcp 连接读取数据
- 从文本文件中读取数据并删除所有换行符空格,并在 C++ 控制台中显示
- Qt TCP服务器不从客户端读取数据
- 累积从 C++11 中的文件中读取数据的整数
- 从 txt 文件中读取数据的最简单方法
- 从 txt 文件中读取数据的 Getline