我正在创建一个简单的服务器,它可以全局存储多个变量。有时这些变量将更新,在此期间变量将从其他线程锁定。访问服务器的每个客户端都被授予自己的线程,但无法更改这些变量,并且基本上是只读的。我对互联网的问题是,我需要担心a)两个线程同时读取同一个变量(不改变)或b)写入变量进程中断读取过程。
我知道在大多数情况下,写一个double不是原子操作,因为它通常不止一个寄存器,但读取操作是否会中断?
由于
答案 0 :(得分:3)
我的第一个猜测是,这与Linux作为操作系统无关。
肯定与使用中的CPU有关,因为有些人可能能够在1次操作中加载/存储双倍的内存。 x86系列有一个FPU的操作码。
它也可以链接到编译器,该编译器可以利用这些CPU能力在1次操作中加载/存储双精度数。不知道gcc做了什么。
答案 1 :(得分:2)
[编辑]道歉,当我最初阅读这个问题并且给出了一个不正确的答案时,我已经不在了,jalf友好地指出了。
我知道在大多数情况下写一个 double不是原子操作 因为它通常不止一个 注册,但可以阅读 操作中断?
是。想象一下,尝试使用两个WORD大小的变量编写自己的IEEE双精度浮点类型。我们无法原子地阅读这两者,因为它们是两个截然不同的部分。在我们尝试阅读的同时,人们可能正在同时进行修改。
我是否需要担心a)两个 读取相同变量的线程 同时(不改变)或b) 写变量过程 打断阅读过程。
a:没有
b:是的
您需要为阅读器使用同步机制(除了编写器之外),或者,如果您像我一样,只需将其设置为共享数据的WORD大小的单精度浮点数,这通常是读取现代系统的原子(虽然你应该验证这一点),坚持原子操作来修改它,避免头痛。
答案 2 :(得分:0)
如果您仅阅读,则不必担心原子性。如果您正在阅读和编写,则需要在“服务器”和“客户端”线程上使用互斥锁。仅在写作时锁定才能完成一半的工作。
现在,根据您的编译器工作和您的确切硬件架构,使用单个双倍可能会有一些运气。请参阅this answer。