我有一个跨线程访问的对象(一种队列)。在由任一线程使用之前,队列对象可以是互斥锁定的。
一种更简单的方法是将锁定置于队列对象本身 - 因此每个API都会锁定队列并在完成工作时释放。这样,线程不必与每个队列一起管理其他互斥变量。
现在我的问题是,有时只有一个线程正在访问队列(比如它是一个局部变量)。但是,由于现在队列本来会首先锁定其内部数据结构并在离开之前解锁,这将是一件代价高昂的事情吗?
冗余mutex_lock和mutex_unlock操作的成本是多少 - 当没有特定的线程同步需求时?
PS: 我的问题与此问题略有关联:How efficient is locking an unlocked mutex? What is the cost of a mutex?
但我正在设计和理解原因的具体答案。
我正在使用C和pthread库。
答案 0 :(得分:1)
处理此问题的一种方法是让队列初始化采用一个参数,指示在队列操作期间是否应该获取锁定。如果一个线程正在使用一个队列,它将被初始化,以便它不会获取/释放锁(或使用一个锁定对象,其中获取/释放操作是nops)。
有关boost :: pool如何在这些行中执行某些操作的示例(请参阅C ++和编译时配置),请参阅此答案:https://stackoverflow.com/a/10188784/12711
类似的概念也可以在运行时应用于C代码。
答案 1 :(得分:0)
首先:C库和pthread都没有实现互斥锁定 - 它们调用内核来使用OS原语。这意味着,静音的性能会随着基本操作系统的不同而变化。
如果你可以将你的可移植性范围降低到支持原子比较交换或原子增加和读取的硬件(例如本千年的任何x86),你可以使用原子增加和读取来创建一个不具有的线程安全队列需要锁定。
对于.Net平台,我在http://sourceforge.net/projects/dotnetlockless有这样的野兽 - 将它移植到C应该很容易。