锁机制(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);

Pthread spinlock自旋锁的更多相关文章

  1. SpinLock 自旋锁, CAS操作(Compare & Set) ABA Problem

    SpinLock 自旋锁 spinlock 用于CPU同步, 它的实现是基于CPU锁定数据总线的指令. 当某个CPU锁住数据总线后, 它读一个内存单元(spinlock_t)来判断这个spinlock ...

  2. SpinLock(自旋锁)

    SpinLock(自旋锁) SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转. 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型 ...

  3. LiteOS:SpinLock自旋锁及LockDep死锁检测

    摘要:除了多核的自旋锁机制,本文会介绍下LiteOS 5.0引入的LockDep死锁检测特性. 2020年12月发布的LiteOS 5.0推出了全新的内核,支持SMP多核调度功能.想学习SMP多核调度 ...

  4. spinlock自旋锁de使用

    Linux内核中最常见的锁是自旋锁.一个自旋锁就是一个互斥设备,它只能有两个值:"锁定"和"解锁".如果锁可用,则"锁定"位被设置,而代码继 ...

  5. 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 百篇博客分析OpenHarmony源码 | v26.02

    百篇博客系列篇.本篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊的好同志 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 当立贞节牌坊 ...

  6. Windows和pthread中提供的自旋锁

    Windows和POSIX中都提供了自旋锁,我们也可以通过C++11的atomic来实现自旋锁.那么两者性能上面是什么关系?先引入实现代码: #ifndef __spinlock_h__ #defin ...

  7. 自旋锁-SpinLock(.NET 4.0+)

    短时间锁定的情况下,自旋锁(spinlock)更快.(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用.所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待.对于多核CPU而 ...

  8. .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)

    本随笔续接:.NET 同步与异步之锁(ReaderWriterLockSlim)(八) 之前的随笔已经说过.加锁虽然能很好的解决竞争条件,但也带来了负面影响:性能方面的负面影响.那有没有更好的解决方案 ...

  9. 抢占式内核与非抢占式内核中的自旋锁(spinlock)的差别

    一.概括 (1)自旋锁适用于SMP系统,UP系统用spinlock是作死. (2)保护模式下禁止内核抢占的方法:1.运行终端服务例程时2.运行软中断和tasklet时3.设置本地CPU计数器preem ...

随机推荐

  1. 查看hadoop压缩方式

    bin/hadoop checknative  来查看我们编译之后的hadoop支持的各种压缩,如果出现openssl为false,那么就在线安装一下依赖包 bin/hadoop checknativ ...

  2. Centos6.5安装rar5.3

    linux下使用最多的压缩工具是gzip,zip等,如果需要使用rar,就必须编译安装了,以下是编译安装rar教程: 一.安装支持库yum install -y gcc gcc-c++ autocon ...

  3. 剑指offer——06二叉树的下一个节点

    题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针.   题目的意思是,在一颗二叉树的中序遍历中,给出其中一 ...

  4. 20130313 word 公式与文字对齐

    1. 就是这儿 然后是这儿 2.这种错误很可能就是进入了死循环 3.复习了字符串现场编写 1.strstr(const char *string, const char *substring):查找s ...

  5. FIR和IIR设计指标

  6. 第一章:Lambda表达式入门概念

    要点:将行为像数据一样传递. 一.几种形式 1.没有参数,用()表示 () ->System.out.println("Hello World"); 2.有且仅有一个参数,省 ...

  7. Nginx安装及分流多个web服务

    Ngnix安装及常用配置 一.安装Nginx 1.检查依赖 yum install gcc-c++ yum install -y pcre pcre-devel yum install -y zlib ...

  8. windows下 Mysql 8.0.x 数据库简单的导出和导入!!!

    1.首先需要进入到mysql安装目录下的bin目录,执行cmd进入命令窗口. 2.导出(导出某个数据库,也可以针对某张表导出)2.1导出数据结构以及数据的命令: mysqldump -u root - ...

  9. @Value的使用

    <Spring源码解析>笔记 使用@Value赋值:1.基本数值2.可以写SpEL: #{}3.可以写${}:取出配置文件[properties]中的值(在运行环境变量里面的值) 1.创建 ...

  10. 概率dp——hdu4089推公式+循环迭代

    迭代是化简公式的常用技巧 dp[i][j]表示队伍中有i人,tomato排在第j位出现情况2的概率,那么先推出公式再进行简化 dp[i][1]=p21*dp[i][i] + p41 j<=k : ...