1

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

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

现在我的问题是,有时只有一个线程正在访问队列(比如说它是一个局部变量)。但既然现在队列本质上会先锁定其内部数据结构并在离开之前解锁,这会是一件代价高昂的事情吗?

当没有特别需要线程同步时,冗余 mutex_lock 和 mutex_unlock 操作的成本是多少?

PS:我的问题与这个问题略有相关:锁定未锁定的互斥锁的效率如何?互斥锁的成本是多少?

但我正在寻找我的设计和理解原因的具体答案。

我正在使用 C 和 pthread 库。

4

2 回答 2

1

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

有关 boost::pool 如何按照这些方式执行某些操作的示例,请参见此答案(尽管在 C++ 中并作为编译时配置):https ://stackoverflow.com/a/10188784/12711

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

于 2012-09-01T06:37:13.173 回答
0

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

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

对于 .Net 平台,我在http://sourceforge.net/projects/dotnetlockless有这样的野兽- 将它移植到 C 应该很容易。

于 2012-08-31T17:27:57.810 回答