Kam*_*Kam 7 c++ concurrency multithreading thread-safety
我一直听说线程安全.究竟是什么以及如何以及在何处学习编写线程安全代码?
另外,假设我有2个线程,一个写入结构,另一个从中读取.这有什么危险吗?有什么我应该寻找的吗?我不认为这是一个问题.两个线程都不会(很不能)在同一时间访问结构.
此外,有人可以告诉我如何在这个例子中:https://stackoverflow.com/a/5125493/1248779我们在并发问题上做得更好.我不明白.
这是一个非常深刻的话题.心脏线程通常是通过同时使用多个核心来使事情变得更快; 或者当你没有很好的方法将操作与'主'线程交错时,在后台进行长时间的操作.后者在UI编程中非常常见.
你的场景是经典的麻烦点之一,也是最早遇到的人之一.拥有一个成员真正独立的结构是很少见的.想要修改结构中的多个值以保持一致性是很常见的.在没有任何预防措施的情况下,很可能修改第一个值,然后让另一个线程读取结构并在写入第二个值之前对其进行操作.
简单的例子是2d图形的'点'结构.您想将点从[2,2]移到[5,6].如果你有一个不同的线程画一条线到那一点你可能很容易画到[5,2].
这真的是冰山一角.有很多好书,但学习这个空间通常是这样的:
显然,这不仅仅是条件变量.但是有很多问题可以通过线程解决,可能几乎有很多方法可以解决,甚至更多的方法可以解决问题.
线程安全是“并发编程”总标题下的一大组问题的一个方面。我建议阅读该主题。
您认为两个线程无法同时访问该结构的假设是不好的。第一:今天我们有多核机器,因此两个线程可以同时运行。其次:即使在单核机器上,分配给任何其他线程的时间片也是不可预测的。您必须预测“其他”线程可能正在处理的任意时间。请参阅下面我的“机会之窗”示例。
线程安全的概念正是为了回答“这有什么危险吗”这个问题。关键问题是,在一个线程中运行的代码是否可能获得某些数据的不一致视图,这种不一致的发生是因为它运行时另一个线程正在更改数据。
在您的示例中,一个线程正在读取结构,同时另一个线程正在写入。假设有两个相关字段:
{ foreground: red; background: black }
Run Code Online (Sandbox Code Playgroud)
作者正在改变这些
foreground = black;
<=== window of opportunity
background = red;
Run Code Online (Sandbox Code Playgroud)
如果读者恰好在那个机会窗口读取值,那么它会看到一个“无意义”的组合
{ foreground: black; background: black }
Run Code Online (Sandbox Code Playgroud)
这种模式的本质是,在我们进行更改的短时间内,系统会变得不一致,读者不应该使用这些值。一旦我们完成更改,就可以安全地再次阅读。
因此,我们使用 Stefan 提到的 CriticalSection API 来防止线程看到不一致的状态。