操作系统基础-第二篇:并发

介绍

线程是操作系统中任务调度器可以调度的最小单元。它类似于进程,但区别于多个线程可以共享同一地址空间。在多线程的进程中,地址空间有多个栈。并发的关键术语:

  • 临界区(critical section):访问共享资源的一段代码。

  • 竞态条件(race condition):多个线程几乎同时进入临界区更新共享数据结构。

  • 不确定性(Indeterminate):程序由一个或多个竞态条件组成,程序输出因运行而异。

  • 互斥(mutex):用于保护共享变量被多个线程同时更新的对象。

  • 原子(atomic):事务要么发生要不一个单个原子操作都不执行。


锁是一个保护共享数据被多个线程同时改变的控制原语。通过使用互斥锁来保护临界区,避免竞态条件,使得事务的执行是原子的。评价锁的标准包括正确性、公平性和性能。

实现互斥锁的策略包括使用TestAndSet或者CompareAndSet原子指令实现的自旋锁和使用队列实现的休眠锁策略。Linux使用的mutex策略是两阶段锁,即先自旋(fastpath)后休眠(slowpath),其中,fastpath的引入可以避免只使用运行-休眠策略带来的频繁切换线程上下文产生的寄存器压力,slowpath的引入可以避免只是用自旋带来的CPU时钟的潜在浪费。

读写锁的实现策略核心是,让第一个获得读锁的读者获取写锁,让最后一个读者释放写锁。通过记录等待写者,可以避免写者饿死。与简单的互斥锁相比,读写锁有更多的CPU开销。


条件变量

条件变量是一个显示队列,当条件不满足时,线程把自己加入等待队列,等待该条件。当条件被改变时,线程唤醒队列中的等待线程。常用于解决的问题包括生产者/消费者问题(producer/consumer)和覆盖条件(covering condition)。注意生产者/消费者问题中的两个条件变量的用法以及使用while检查条件避免假唤醒(spurious wakeup)以及某些线程库的signal唤醒两个线程的情况。


信号量

信号量是一个根据值的正负来控制多线程访问临界区的变量。其支持的语义:

  • wait:让信号量的值减一。如果其值为负数,那么wait线程进行等待。

  • signal:让信号量的值加一。如果加之前的值为负数,那么唤醒一个等待线程。


基于事件循环的并发

除了多线程并发模型外,基于事件循环的并发模型也是一个常用的模型。其基础一般是事件循环+异步io。在事件循环的问题中,我们一般需要处理阻塞的问题以及使用异步io带来的状态管理问题。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值