有两个主题,一个只读取signal
,另一个只设置signal
。
是否有必要为signal
创建一个互斥锁?原因是什么?
更新
我所关心的是,如果两个线程读取/设置相同的时间,它是否会崩溃
答案 0 :(得分:2)
你可能想要使用原子变量,虽然互斥量也可以。
问题在于无法保证数据在线程之间保持同步,但使用原子变量可确保只要一个线程更新该变量,其他线程就会立即读取其更新值。
如果一个线程更新缓存中的变量,第二个线程从内存中读取变量,则可能会出现问题。如果缓存尚未刷新到内存,则第二个线程将读取变量的过期值。原子变量确保变量的值在线程之间保持一致。
如果您不关心及时的变量更新,您可以使用单个volatile变量。
答案 1 :(得分:1)
这取决于。如果写入是原子的,那么您不需要互斥锁。如果写入不是原子的,那么你需要锁定。
还存在编译器在CPU缓存中缓存变量的问题,这可能导致主存储器中的副本在每次写入时都不会更新。有些语言告诉编译器不要像CPU那样缓存CPU中的变量(Java中的volatile关键字),或者告诉编译器将任何缓存的值与主存储器同步(Java中的synchronized关键字)。但是,互斥体通常不能解决这个问题。
答案 2 :(得分:0)
如果您需要的只是线程之间的同步(一个线程必须在另一个线程开始之前完成某些事情),那么就不需要互斥。
只有当线程共享某些资源时才需要相互排除,如果资源在大致相同的时间运行通过临界区,则资源可能会被破坏。想想两个人共用一个银行账户,同时在两个不同的ATM上。
根据您的语言/线程库,您可以使用相同的同步机制来完成互斥 - 信号量或监视器。所以,如果你正在使用Pthreads,这里有人可以发布一个同步的例子,另一个用于互斥。如果它的java,会有另一个例子。也许您可以告诉我们您正在使用的语言/库。
答案 3 :(得分:0)
如果你在编辑中说过,你只想确保崩溃,那么你不需要做任何事情(至少作为一项规则)。如果线程之间发生冲突,那么最糟糕的情况就是数据会被破坏 - 例如,读者可能得到一个已经部分更新的值,并且不直接对应于写线程所写的任何值。经典的例子是你添加了一些东西的多字节数字,并且有一个进位,(例如)旧的值是0x3f ffff,它正在递增。读取线程可能会看到0x3f 0000,其中低16位已递增,但进位到高16位尚未发生(尚未)。
在现代机器上,这个小数据项的增量通常是原子的,但是它会有一些大小(和对齐) - 通常,如果变量的一部分在一个高速缓存行中,并且相反,它将不再是原子的。确切的大小和对齐方式有所不同,但基本思路保持不变 - 这主要是因为数字有足够的数字才能发生。
当然,如果你不小心,像这样的东西可能导致你的代码陷入僵局或者那个订单上的某些东西 - 如果你不知道怎么计划就不可能猜出会发生什么使用数据。