互斥量,条件变量,信号量,读写锁,自旋锁

互斥量,条件变量,信号量,读写锁,自旋锁
  • 互斥锁–保护了一个临界区,在这个临界区中,一次最多只能进入一个线程。如果有多个进程在同一个临界区内活动,就有可能产生竞态条件(race condition)导致错误,其中包含递归锁和非递归锁,(递归锁:同一个线程可以多次获得该锁,别的线程必须等该线程释放所有次数的锁才可以获得)。

  • 读写锁–从广义的逻辑上讲,也可以认为是一种共享版的互斥锁。可以多个线程同时进行读,但是写操作必须单独进行,不可多写和边读边写。如果对一个临界区大部分是读操作而只有少量的写操作,读写锁在一定程度上能够降低线程互斥产生的代价。

  • 条件变量–允许线程以一种无竞争的方式等待某个条件的发生。当该条件没有发生时,线程会一直处于休眠状态。当被其它线程通知条件已经发生时,线程才会被唤醒从而继续向下执行。条件变量是比较底层的同步原语,直接使用的情况不多,往往用于实现高层之间的线程同步。使用条件变量的一个经典的例子就是线程池(Thread Pool)了。

  • 信号量–通过精心设计信号量的PV操作,可以实现很复杂的进程同步情况(例如经典的哲学家就餐问题和理发店问题)。而现实的程序设计中,却极少有人使用信号量。能用信号量解决的问题似乎总能用其它更清晰更简洁的设计手段去代替信号量。

  • 自旋锁–当要获取一把自旋锁的时候又被别的线程持有时,不断循环的去检索是否可以获得自旋锁,一直占CPU资源。

  • 对于这些同步对象,有一些共同点:

    1. 每种类型的同步对象都有一个init的API,它完成该对象的初始化,在初始化过程中会分配该同步对象所需要的资源(注意是为支持这种锁而需要的资源,不包括表示同步对象的变量本身所需要的内存)
    2. 每种类型的同步对象都一个destory的API,它完成与init相反的工作
    3. 对于使用动态分配内存的同步对象,在使用它之前必须先调用init
    4. 在释放使用动态分配内存的同步对象所使用的内存时,必须先调用destory释放系统为其申请的资源
    5. 每种同步对象的默认作用范围都是进程内部的线程,但是可以通过修改其属性为PTHREAD_PROCESS_SHARED并在进程共享内存中创建它的方式使其作用范围跨越进程范围
    6. 无论是作用于进程内的线程,还是作用于不同进程间的线程,真正参与竞争的都是线程(对于不存在多个线程的进程来说就是其主线程),因而讨论都基于线程来
    7. 这些同步对象都是协作性质的,相当于一种君子协定,需要相关线程主动去使用,无法强制一个线程必须使用某个同步对象
  • 总体上来说,可以将它们分为两类:

    1. 第一类是互斥锁、读写锁、自旋锁,它们主要是用来保护临界区的,也就是主要用于解决互斥问题的,当尝试上锁时大体上有两种情况下会返回:上锁成功或出错,它们不会因为出现信号而返回。另外解锁只能由锁的拥有着进行
    2. 第二类是条件变量和信号量,它们提供了异步通知的能力,因而可以用于同步和互斥。但是二者又有区别:
      1. 信号量可以由发起P操作的线程发起V操作,也可以由其它线程发起V操作;但是条件变量一般要由其它线程发起signal(即唤醒)操作
      2. 由于条件变量并没有包含任何需要检测的条件的信息,因而对这个条件需要用其它方式来保护,所以条件变量需要和互斥锁一起使用,而信号量本身就包含了相关的条件信息(一般是资源可用量),因而不需要和其它方式一起来使用
      3. 类似于三种锁,信号量的P操作要么成功返回,要么失败返回,不会因而出现信号而返回;但是条件变量可能因为出现信号而返回,这也是因为它没包含相关的条件信息而导致的。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_长风_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值