2011-06-21 71 views
3

这将在没有互斥体的情况下完成。我只想知道它是否是线程安全的,即程序不会崩溃或类似。我并不在乎变量在读取时可能处于错误状态,因为结果不是致命的(只有在不需要时才会影响小数据结构的副本) 我正在使用Qt。我可以从线程A写入一个变量,同时从线程B读取相同的变量

以下是可能发生的情况:从主线程中,我将设置一个bool,它是qthread的成员。当我将bool设置为true时或之后,qthread可能位于使用此bool的函数中(这是由主线程和qthread使用的函数,所有内容都已被保护并同步,因此没有函数由两个线程同时运行)

有点想起它,因为这个布尔只被主线程使用反正我会检查哪个线程在函数中,应该解决,但我仍然好奇。

+0

如果你想基于你的布尔同步线程,你应该使用某种等待事件。 –

+0

@Tony,不,不,不用于同步线程。 –

回答

10

你似乎在问什么是良性种族。

例如,考虑一个整数变量,表示在0到100范围内的进度值。当您从另一个线程递增时,您可以从一个线程读取它。您不介意在写入之前读取值,还是在写入之后读取值。你会很快再读一遍,然后在写完之后你会得到价值。 在这种情况下,比赛是良性的。然而,什么可能不是良性的东西叫撕裂。硬件可能允许您读取值,而只有部分内存已被其他线程写入。

例如,写入线程可能写入低位字,然后读取两个字,然后写入高位字。撕裂会导致不正确。

硬件确实提供关于撕裂的保证,但是它们在不同的架构之间有所不同。例如,对于4字节对齐的4字节宽的数据,x86具有原子访问,即不撕裂。

如果您正在编写可移植代码,那么您处于相当棘手的水域,因为当前的标准不能保证原子性。如果你可以在你的硬件平台上做出假设,那么你可能会利用良性的比赛。

+0

好的谢谢,答案很多。我现在明白如果所讨论的变量是一个指针,撕裂对程序来说可能是致命的。在我的情况下,它是一个不应该导致致命堕胎的布尔。无论如何,我仍然会避免这样做。 –

+1

这里有一篇关于良性种族潜在问题的有趣文章:[http://blog.corensic.com/2011/06/07/benign-data-races-considered-harmful/](http://blog。 corensic.com/2011/06/07/benign-data-races-considered-harmful/)。 –

2

你可以在没有互斥但不写的情况下阅读。如果多个线程将写入您的变量,您需要有某种同步机制来保护它。

如果线程B在线程A完成写入之前读取,如果这不是简单类型,而是一些复杂类型,则可能会出现不一致状态。

+5

即使对于简单类型,也可能会出现不一致。 –

+0

@Oli,我想这是因为没有写保证是原子的? –

+0

我不关心如果我得到一个错误,而是我不想访问违规或分段错误或崩溃 –

1

你没有提到一个平台,但是如果你是一个Windows系统,在处理更简单的类型时,你一定要看看::Interlocked...家族的SDK函数。

+0

我通常在Linux发行版上,但感谢提示。 –

相关问题