在C中,我有一个声明为volatile且初始化为null的指针。
void* volatile pvoid;
线程1偶尔会读取指针值以检查它是否为非null。线程1不会设置指针的值。 线程2只会将指针的值设置一次。
我相信我可以在不使用互斥锁或条件变量的情况下逃脱 是否有任何原因线程1将读取损坏的值或线程2将写入损坏的值?
答案 0 :(得分:3)
为了使线程安全,你必须对变量进行原子读/写操作,它在所有时序情况下都是不安全的。在Win32下有Interlocked函数,在Linux下你可以build it yourself with assembly如果你不想使用重量级互斥和条件变量。
如果您不反对GPL,那么http://www.threadingbuildingblocks.org及其atomic<>
模板似乎很有希望。 lib是跨平台的。
答案 1 :(得分:2)
如果值适合单个寄存器,例如内存对齐指针,则这是安全的。在其他可能需要多条指令来读取或写入值的情况下,读取线程可能会损坏数据。如果您不确定读写将在所有使用场景中采用单个指令,请使用原子读写。
答案 2 :(得分:0)
不幸的是,你无法对纯C中的原子进行任何假设。
但是,GCC确实提供了一些原子内置函数,它们可以为您提供适用于许多体系结构的正确指令。有关详细信息,请参阅Chapter 5.47 of the GCC manual。答案 3 :(得分:0)
这看起来很好..在这种情况下唯一的问题就会发生 让线程A成为你的检查线程,B是修改线程。 问题是检查相等性在技术上不是首先应该将值复制到寄存器然后检查然后恢复。让我们假设线程A已复制到寄存器,现在B决定更改值,现在变量的值会发生变化。因此,当控制返回到A时,它会说它不是空的,即使SHUD是根据调用线程的时间。这个程序似乎无害,但可能导致问题......
使用互斥...简单的enuf ..你可以确定你没有同步错误!
答案 4 :(得分:0)
取决于您的编译器,架构和操作系统。 POSIX(因为这个问题被标记为pthreads我假设我们不是在谈论窗口或其他一些线程模型)而且C没有给出足够的约束来对此问题进行可移植的回答。
安全假设当然是用互斥锁来保护对指针的访问。但是根据您对问题的描述,我想知道pthread_once是不是更好的方法。当然,问题中没有足够的信息可以用这种方式说出来。
答案 5 :(得分:-2)
在大多数可以在单个指令中读取/写入指针值的平台上,它已设置或尚未设置。它不能在中间中断并包含损坏的值。在这种平台上不需要互斥锁。