C 当线程同步不重要时,互斥锁的成本有多高?

C 当线程同步不重要时,互斥锁的成本有多高?,c,locking,pthreads,mutex,C,Locking,Pthreads,Mutex,我有一个跨线程访问的对象(类似于队列)。队列对象在被任一线程使用之前都可以被互斥锁 管理这一点的一种更简单的方法是将锁放在队列对象本身内部,因此每个API都将锁定队列,并在工作完成时释放。这样,线程就不必在每个队列中管理额外的互斥变量 现在我的问题是,有时只有一个线程在访问队列(假设它是一个局部变量)。但是,由于现在队列首先会锁定其内部数据结构,并在离开之前解锁,这会是一件代价高昂的事情吗 在不需要线程同步的情况下,冗余互斥锁和互斥解锁操作的成本有多高 附言: 我的问题与此略有关联: 但我正在寻

我有一个跨线程访问的对象(类似于队列)。队列对象在被任一线程使用之前都可以被互斥锁

管理这一点的一种更简单的方法是将锁放在队列对象本身内部,因此每个API都将锁定队列,并在工作完成时释放。这样,线程就不必在每个队列中管理额外的互斥变量

现在我的问题是,有时只有一个线程在访问队列(假设它是一个局部变量)。但是,由于现在队列首先会锁定其内部数据结构,并在离开之前解锁,这会是一件代价高昂的事情吗

在不需要线程同步的情况下,冗余互斥锁和互斥解锁操作的成本有多高

附言: 我的问题与此略有关联:

但我正在寻找一个具体的答案,在我的设计和理解为什么


我正在使用C和pthread库

首先:C库和pthread都没有实现互斥锁——它们调用内核来使用操作系统原语来实现互斥锁。这意味着,静音的性能将随着基本操作系统的不同而变化很大

如果您可以将可移植性降低到支持原子比较交换或原子增加和读取(如本世纪的任何x86)的硬件,那么您可以使用原子增加和读取来创建不需要锁定的线程安全队列


对于.Net平台,我有这样一个beast——将它移植到C应该很容易。

首先:C库和pthreads都没有实现互斥锁——它们调用内核来使用操作系统原语。这意味着,静音的性能将随着基本操作系统的不同而变化很大

如果您可以将可移植性降低到支持原子比较交换或原子增加和读取(如本世纪的任何x86)的硬件,那么您可以使用原子增加和读取来创建不需要锁定的线程安全队列


对于.Net平台,我有这样一个beast at-将它移植到C应该很容易。

处理这个问题的一种方法是让队列初始化获取一个参数,该参数指示在队列操作期间是否应该获取锁。如果一个队列正被一个线程使用,它将被初始化,这样它就不会获取/释放锁(或者使用一个锁对象,其中获取/释放操作是nops)

参见这个例子,一个关于Booo::池如何沿着这些行做一些事情的例子(虽然在C++和编译时配置中):


类似的概念也可以在运行时应用于C代码。

处理此问题的一种方法是让队列初始化获取一个参数,该参数指示在队列操作期间是否应获取锁。如果一个队列正被一个线程使用,它将被初始化,这样它就不会获取/释放锁(或者使用一个锁对象,其中获取/释放操作是nops)

参见这个例子,一个关于Booo::池如何沿着这些行做一些事情的例子(虽然在C++和编译时配置中):


类似的概念也可以在运行时应用于C代码。

测试它。它应该足够简单,可以装配一个快速测试no?为什么不编写一个简单的程序,在循环中执行数千次锁定/解锁操作,并测量它需要多长时间?这将为您提供一个很好的估计,当没有资源争用时,单个锁定/解锁将增加多少开销。互斥锁性能将取决于pthreads实现。pthread在Linux、osx、Windows和其他平台之间具有(有时是完全不同的)不同的性能特征,因为它们将使用不同的本机api。我们在谈论什么平台?没有单一的答案,因为不同平台的成本可能不同。而且没有“大”或“小”成本,您需要将其与其他操作进行比较。看看不同的框架提供了什么,我将创建两个结构:一个带锁,一个不带锁。这样,需要锁的人就可以使用锁,不需要锁的人就可以使用不带锁的变体。现在在Linux内核上,pthreads使用futex,如果没有争用,就永远不应该调用内核。测试它。它应该足够简单,可以装配一个快速测试no?为什么不编写一个简单的程序,在循环中执行数千次锁定/解锁操作,并测量它需要多长时间?这将为您提供一个很好的估计,当没有资源争用时,单个锁定/解锁将增加多少开销。互斥锁性能将取决于pthreads实现。pthread在Linux、osx、Windows和其他平台之间具有(有时是完全不同的)不同的性能特征,因为它们将使用不同的本机api。我们在谈论什么平台?没有单一的答案,因为不同平台的成本可能不同。而且没有“大”或“小”成本,您需要将其与其他操作进行比较。看看不同的框架提供了什么,我将创建两个结构:一个带锁,一个不带锁。这样,需要锁的人就可以使用锁,不需要锁的人就可以使用不带锁的变体。现在在Linux内核上,pthreads使用futex,如果没有争用,就永远不应该调用内核。除非实现非常糟糕,否则只有在争用时才需要内核帮助,在这种情况下,性能几乎100%取决于C/pthreads库。“无锁队列”的最大缺点是,如果消费者遇到一个空队列,它就无法进入睡眠状态,并且在执行任务时无法被唤醒