primefacesvariables是否是无锁的?
当我们谈论primefacesvariables,例如C ++ 11的atomic<>
,它是否可以自由locking? 或者是无锁的东西有所不同? 如果我用primefacesvariablespipe理一个队列,它会比一个无锁队列慢吗?
标准不指定primefaces对象是否是无锁的。 在不为Ttypes提供无锁primefaces操作的平台上, atomic<T>
对象可以使用一个互斥体来实现,这个互斥体不会是无锁的。 在这种情况下,在实现中使用这些对象的容器也不会无锁。
该标准提供了一种检查atomic<T>
variables是否是无锁的方法:可以使用var.is_lock_free()
或atomic_is_lock_free(&var)
。 这些函数保证在给定的程序执行中始终返回相同typesT
的相同值。 对于像int
这样的基本types,还提供了macros(例如ATOMIC_INT_LOCK_FREE
),用于指定是否可以使用该types的无锁primefaces访问。
无锁通常适用于multithreading之间共享的数据结构,其中同步机制不互斥; 意图是所有线程都应该继续取得某种进展,而不是睡在互斥体上。
atomic<T>
variables不使用锁(至less在你的平台上T
是原生的primefaces),但是它们在上面的意义上并不是无锁的。 你可以使用它们来实现一个无锁的容器,但是它们本身是不够的。
例如, atomic<queue<T>>
不会突然将一个正常的std::queue
变成一个无锁的数据结构。 然而,你可以实现一个真正无锁的atomic_queue<T>
它的成员是atomic
。
请注意,即使atomic<int>
是原生的primefaces,并且不会在您的平台上使用锁进行模拟,也不会以任何有趣的方式使其无锁 。 在这个意义上,Plain int
已经是无锁的: atomic<>
封装器可以显式控制内存sorting,并访问硬件同步原语。
抛开市场和冷静因素,对于神奇的C ++语法(棕色)糖是否实现了直接的公交车locking或互斥(这可能依靠公交车locking,但如评论员指出的那样,操作系统内部的优势是以更有效的方式来实现),或者如果你不幸在单处理器体系结构上运行,那么根本就没有任何东西。
互斥锁已经在语义上locking了空闲。 它们实现了所有你可能想到的调度程序的好处,即优先级反转处理和重入。 你不能在一个互斥锁上死锁(实际上,如果你非常努力的话,你可能会这样做,但是就一个variables而言,你不会这么做),而且使用互斥锁对其他进程没有任何明显的副作用,操作系统比总线lockingvariables。
唯一的区别是,程序员可能(通过devise或错误)持有一个不合理的时间的互斥量,而同样不称职的程序员可能会轮询“等待”variables,并获得相同的愚蠢结果,带来灾难性公共汽车速度放慢,这会给整个系统带来更多的压力,而不是一个错误的互斥使用(好的,我以前所说的BSOD只是一个less年的挑衅,尽pipe我仍然怀疑一些司机可能不会对总线争吵)。 无论如何,这个问题很快就解决了,当互斥调用是围绕一个线性访问相当小的内存。
“locking自由”正在向梦想的硬编程人员出售梦想。 我觉得很有意思的是,一个依赖locking多处理器总线的机制可能被称为那个。
一个“无锁”variables的访问是通过中断总线高速caching系统,禁止总线访问调度,以及通常禁用所有允许你的平均多处理器总线做一个体面的工作的机制来硬件纠缠。
每当你访问一个“locking免费”的魔术variables时,你就在公交控制器的齿轮上投下一把沙子。
像任何并发访问机制一样,总线lockingvariables(对不起,我的意思是“locking自由variables”)代价高昂,并且具有极其难以预测甚至诊断的负面副作用。
只要你使用这些新的有光泽的玩具,就像你会互斥,也就是非常稀疏,只有几个很好的理由(不行,超级酷的先生等待不是其中之一),没关系。
但是,如果你开始在所有地方喷洒公交车锁,或者(上帝保佑!) 投票lockingvariables作为一个便宜和容易的替代适当的同步对象(什么超级酷先生等待免费可能会叫“酝酿自己的自制螺旋锁在3个简单的步骤“),你只能设法将你的代码运行的任何尖端硬件转换到大约1995年的Pentium I仿真器。