在一个程序,我的工作,我有很多的代码如下:
pthread_mutex_lock( &frame->mutex );
frame->variable = variable;
pthread_mutex_unlock( &frame->mutex );
这显然是CPU周期的浪费如果中间指令可以只用原子商店来替代。 我知道,海湾合作委员会,颇能这一点,但我一直没能找到这种简单的线程安全的原子操作多文档。 我怎么会用一个原子操作替换这套代码?
(我知道简单的商店理论上应该是原子的,但是我不希望有希望优化不是在过程中的某一时刻搞砸了其原子岬。)
澄清:我不需要他们严格原子; 这些变量仅用于线程同步。 也就是说,线程B读取值,检查其是否正确,如果其不正确,它睡觉。 所以,即使线程A更新值和线程B并没有意识到它的更新,这不是一个问题,因为这只是意味着当它没有真正的线程B睡觉需要,当它醒来时,该值将是正确的。
你可以查阅gcc文档。 对于当前的gcc版本(4.3.2),这将是章节5.47 用于原子存储器存取内置功能 -用于其他版本的GCC请检查您的文档。 它应该是在第二章5扩展到C语言家族。
顺便说一句,C编译器,使完全没有保证,以简单的存储操作是原子的。 你可以不依赖于这样的假设。 为了使机器操作码被自动执行,它需要锁定前缀。
达到一定点,在C原子操作从经由atomic.h中报头中的内核源代码直设置。
然而,有直接用在用户空间代码内核头文件是一个非常不好的做法,所以atomic.h中头文件前一段时间被删除。 相反,我们现在CA利用“GCC原子内建命令”,这是一个更好的,更可靠的方法。
有一个由铎Golubenco在他的博客提供了很好的解释 。 他甚至提供了一个简易替换初始atomic.h中的文件,如果你有一些代码,需要它。
可惜我是新来的StackOverflow,所以我只能用一个链接在我的意见,所以检查铎的职位,并得到启发。
在x86和大多数其他架构,对齐4个字节的读写总是原子。 优化器可以跳过/重新排序的读取和在一个线程中写道,虽然。
你想要做的就是告诉其他线程可能已经触及该内存位置的编译器。 (的副作用pthread_mutex_lock
告诉其他线程可能已经触及内存的任何部分的编译器。)您可能会看到volatile
建议,但这不是在C规范,GCC不解释volatile
的方式。
asm("" : "=m" (variable));
frame->variable = variable;
是一个特定的GCC-机制的说法是“ variable
已经被写入,重新加载它。”
据我所知,你不能前缀LOCK MOV指令; 这只是针对RMW操作允许的。 但是,如果他用一个简单的店,他可能还需要一个内存屏障,这是隐含的与互斥,以及与允许LOCK指令。
我所看到的,您使用的GNU开发平台,所以它是安全地说,GLIC提供了一个数据类型INT范围与原子的能力, 'sig_atomic_t'
。 因此,这种方法可以在内核级别向你保证原子操作。 不GCC水平。