全局变量多读一写多线程安全? 我试图用C++编写一个程序,其中一个全局变量由多个线程读取并由一个线程更新。在这种情况下,我是否需要像这样编写任何信号量,或者我可以让它保持原样,因为实际上只有一个线程正在写入全局变量,因此不存在可能的争用条件

全局变量多读一写多线程安全? 我试图用C++编写一个程序,其中一个全局变量由多个线程读取并由一个线程更新。在这种情况下,我是否需要像这样编写任何信号量,或者我可以让它保持原样,因为实际上只有一个线程正在写入全局变量,因此不存在可能的争用条件,c++,multithreading,race-condition,C++,Multithreading,Race Condition,我也是一个信号灯新手,所以如果可能的话,我需要省去自己的麻烦 计划如下: 写入线程:不断检查引脚是否存在高电压,高电压时设置全局变量 读者线程:不断检查无限循环中的全局变量,并在设置它时执行某些操作。您需要提供更多上下文,但一般来说,您应该使用类似的同步原语来保护对该变量的访问。如果您不关心某些线程是否读取了不正确的值,您可以放宽需求,但这一切都取决于您的用例 您可以将问题中的“多个读卡器”简化并替换为“单个读卡器”,答案仍然是:您必须保护来自不同线程的共享变量访问,否则读卡器线程可能无法“观察

我也是一个信号灯新手,所以如果可能的话,我需要省去自己的麻烦

计划如下: 写入线程:不断检查引脚是否存在高电压,高电压时设置全局变量


读者线程:不断检查无限循环中的全局变量,并在设置它时执行某些操作。

您需要提供更多上下文,但一般来说,您应该使用类似的同步原语来保护对该变量的访问。如果您不关心某些线程是否读取了不正确的值,您可以放宽需求,但这一切都取决于您的用例

您可以将问题中的“多个读卡器”简化并替换为“单个读卡器”,答案仍然是:您必须保护来自不同线程的共享变量访问,否则读卡器线程可能无法“观察”编写器线程所做的更改,并最终读取和使用错误的值


如果您试图从线程中读取/修改的是一个简单的整数,那么您可以使用。

您需要提供更多的上下文,但一般来说,您应该使用类似的同步原语来保护对该变量的访问。如果您不关心某些线程是否读取了不正确的值,您可以放宽需求,但这一切都取决于您的用例

您可以将问题中的“多个读卡器”简化并替换为“单个读卡器”,答案仍然是:您必须保护来自不同线程的共享变量访问,否则读卡器线程可能无法“观察”编写器线程所做的更改,并最终读取和使用错误的值


如果您试图从线程中读取/修改的是一个简单的整数,那么您可以使用。

如果不知道在您的特定情况下正确的程序是什么,很难说。但是,只要您只有一个并发编写器,您就不必担心会损坏内存


不过,多个读卡器将在不锁定的情况下获得不确定的值。您肯定希望使用该值,并且您可能希望查看
volatile
关键字,以防止将值存储在寄存器中,如果这是应用程序中的一个问题。

如果不知道在您的特定情况下什么将构成正确的程序,很难说。但是,只要您只有一个并发编写器,您就不必担心会损坏内存


不过,多个读卡器将在不锁定的情况下获得不确定的值。你肯定会想使用这个值,如果应用程序中存在此问题,您可能希望查看
volatile
关键字,以防止将值存储在寄存器中。

很简单:如果多个线程可以同时访问一个对象而不进行同步,并且其中至少有一个线程正在写入该对象,则程序存在数据竞争。具有数据竞争的程序的行为是未定义的

您可以通过防止使用互斥对象同时访问来提供同步,或者在许多情况下,通过使用原子对象来提供同步


如果你没有正确地同步读写,你可以享受流行的客厅游戏“猜这个程序可能会做什么”。有许多消息线程为为什么在某些情况下数据竞争是正常的提供了合理的解释。如果你真的不在乎你的程序是否能正常运行,那就好了。如果需要,请同步。

这很简单:如果多个线程可以在不同步的情况下同时访问一个对象,并且其中至少有一个线程正在向该对象写入数据,则该程序存在数据竞争。具有数据竞争的程序的行为是未定义的

您可以通过防止使用互斥对象同时访问来提供同步,或者在许多情况下,通过使用原子对象来提供同步


如果你没有正确地同步读写,你可以享受流行的客厅游戏“猜这个程序可能会做什么”。有许多消息线程为为什么在某些情况下数据竞争是正常的提供了合理的解释。如果你真的不在乎你的程序是否能正常运行,那就好了。如果你在乎,请同步。

volatile在这里绝对帮不上忙。@Pavel-我不知道你为什么这么说。如果全局变量是裸int,那么将其传递到接受volatile int引用的函数中就是重新加载值和缓存值之间的区别。关于几个不同的场景,请参见本文。根据OP的要求,使用volatile是可以的(但是根本不涉及线程安全)。但是,
volatile
绝不会提供线程安全性。即使是常规的atomic也可能无法提供,这取决于您使用atomics。很抱歉,我没有说为什么它“绝对显示”,而事实上,您发布的代码显示了相反的结果,我最初没有回顾asm:)x86具有强内存模型,所以它恰好是使用volatile时生成的相同代码。例如,在手臂上,它绝对不会是相同的。将ARM编译器添加到示例中,您将看到。检查一下我们的挥发油绝对帮不上忙。@Pavel-我不知道你为什么这么说。如果全局变量是裸int,那么将其传递到接受volatile int引用的函数中就是重新加载值和缓存值之间的区别。关于几个不同的场景,请参见本文。根据OP的要求,使用volatile是可以的(但是根本不涉及线程安全)。但是,
volatile