锁机制(lock) 是多线程编程中最常用的同步机制,用来对多线程间共享的临界区(Critical Section) 进行保护。

Pthreads提供了多种锁机制,常见的有:
1) Mutex(互斥量):pthread_mutex_***
2) Spin lock(自旋锁):pthread_spin_***
3) Condition Variable(条件变量):pthread_con_***
4) Read/Write lock(读写锁):pthread_rwlock_***

在多线程编中,根据应用场合的不同,选择合适的锁来进行同步,对多线程程序的性能影响非常大. 本文主要对 pthread_mutex 和 pthread_spinlock 两种锁制机进行比较,并讨论其适用的场合.

1 Pthread mutex

Mutex属于sleep-waiting类型的锁. 从 2.6.x 系列稳定版内核开始, Linux 的 mutex 都是 futex (Fast-Usermode-muTEX)锁.
futex(快速用户区互斥的简称)是一个在Linux上实现锁定和构建高级抽象锁如信号量和POSIX互斥的基本工具。它们第一次出现在内核开发的2.5.7版;其语义在2.5.40固定下来,然后在2.6.x系列稳定版内核中出现。
Futex 是由Hubertus Franke(IBM Thomas J. Watson 研究中心), Matthew Kirkwood,Ingo Molnar(Red Hat)和 Rusty Russell(IBM Linux 技术中心)等人创建的。
Futex 是由用户空间的一个对齐的整型变量和附在其上的内核空间等待队列构成. 多进程或多线程绝大多数情况下对位于用户空间的futex 的整型变量进行操作(汇编语言调用CPU提供的原子操作指令来增加或减少),而其它情况下,则需要通过代价较大的系统调用来对位于内核空间的等待队列进行操作(如唤醒等待的进程/线程,或 将当前进程/线程放入等待队列). 除了多个线程同时竞争锁的少数情况外,基于 futex 的 lock 操作是不需要进行代价昂贵的系统调用操作的.
.
这种机制的核心思想是通过将大多数情况下非同时竞争 lock 的操作放到在用户空间来执行,而不是代价昂贵的内核系统调用方式来执行,从而提高了效率.

Pthreads提供的Mutex锁操作相关的API主要有:
1、 pthread_mutex_lock (pthread_mutex_t *mutex);
2、 pthread_mutex_trylock (pthread_mutex_t *mutex);
3、 pthread_mutex_unlock (pthread_mutex_t *mutex);

因为源代码比较长,这里不做摘录,大家可以参考:
glibc-2.12.2/nptl/pthread_mutex_lock.c

2 Pthread spinlock

spinlock,也称自旋锁,是属于busy-waiting类型的锁.在多处理器环境中, 自旋锁最多只能被一个可执行线程持有。如果一个可执行线程试图获得一个被争用(已经被持有的)自旋锁,那么该线程就会一直进行忙等待,自旋,也就是空转,等待锁重新可用。如果锁未被争用,请求锁的执行线程便立刻得到它,继续执行。

一个被争用的自旋锁使得请求它的线程在等待锁重新可用时自旋,特别的浪费CPU时间,所以自旋锁不应该被长时间的持有。实际上,这就是自旋锁的设计初衷,在短时间内进行轻量级加锁。

Kernel中的自旋锁不能够在能够导致睡眠的环境中使用。举个例子,一个线程A获得了自旋锁L;这个时候,发生了中断,在对应的中断处理函数B中,也尝试获得自旋锁L,就会中断处理程序进行自旋。但是原先锁的持有者只有在中断处理程序结束后,采用机会释放自旋锁,从而导致死锁。
由于涉及到多个处理器环境下,spin lock的效率非常重要。因为在等待spin lock的过程,处理器只是不停的循环检查,并不执行其他指令。但即使这样, 一般来说,spinlock的开销还是比进程调度(context switch)少得多。这就是spin lock 被广泛应用在多处理器环境的原因

Pthreads提供的与Spin Lock锁操作相关的API主要有:
pthread_spin_lock (pthread_spinlock_t *lock);
pthread_spin_trylock (pthread_spinlock_t *lock);
pthread_spin_unlock (pthread_spinlock_t *lock);

最新文章

  1. eclipse里打开SWT项目找不到source/design的图形UI设计界面
  2. [Android]用图库打开指定的文件夹,没错是第一个画面直接是图库的文件夹画面
  3. Gold Game
  4. C# Interlocked 笔记
  5. hdu 1233 还是畅通工程 解题报告
  6. 基于session的简易购物车引发的问题
  7. EMVTag系列7《静态签名数据》
  8. java web路径的问题
  9. [oc] instancetype vs id for Objective-C 【转】
  10. redis对比memcached
  11. asp.net在类库中使用EF 6.0时的相关配置
  12. Sequelize 基本操作
  13. TortiseGit 添加SSH-Key
  14. 用SQL表达交并差操作
  15. [LeetCode] 12,13 整数和罗马数互转
  16. echarts + timeline 显示多个options
  17. iOS UI基础-21 WKWebView
  18. C# Bitmap长宽参数构造的图片对象的每个像素ARGB都是0
  19. 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片)
  20. libgdx游戏引擎教程

热门文章

  1. NX二次开发-UFUN计时函数UF_end_timer
  2. 解决Oracle迁移至GreenPlum(PostgreSql)后不支持rownum的问题
  3. Mysql 提交Big sql的过程
  4. Putty 两步代理访问互联网
  5. 14-Ubuntu-文件和目录命令-查看目录内容-ls-1
  6. 【POJ】2492 A Bug's Life
  7. FlyMcu下载时的问题
  8. Tomcat Geoserver等服务器 端口号修改
  9. arm-linux-ar 和 arm-linux-ranlib 的使用
  10. 两个table合并