【Linux应用编程】互斥与同步要点



1 前言

  linux系统是一个多用户、多任务的现代操作系统,同时任务间(进程)又可细分为多个线程。操作系统在调度用户任务过程,必须遵循用户指定的规则进行,否则不能达到用户预期功能,甚至引起系统异常。操作系统上的多个任务,在宏观上是“并行执行”,用户必须按照互斥或者同步的一种机制,实现资源共享和进程(线程)协作,避免资源冲突,保证程序地正确执行。典型的任务模型:

  • 多个任务访问同一资源
  • 任务间存在依赖关系和先后顺序

2 临界资源

   临界资源指的是多个进程(线程)共享的,并且可能同时访问的资源,典型直观的物理共享资源就是打印机,A和B同时请求打印,打印过程必然是有先后顺序的。临界资源一次只允许一个进程(线程)访问。我们知道进程是操作系统资源分配的基本单位,线程是任务调度和执行的基本单位,不同进程拥有独立的代码空间和内存资源,同一进程下的线程是共享当前进程的所有系统资源。 线程间的所有共享的资源都可以理解为“临界资源”。典型的临界资源包括:

  • 共享内存
  • 文件描述符
  • 堆栈空间
  • 全局变量

2.1 临界区

  进程(线程)访问临界资源的一段程序称为临界区。从临界区含义看,是先有临界资源再有临界区。对临界资源的互斥访问即是确保多个进程(线程)互斥地进入自己的临界区。一个进程(线程)进入临界区意味着占用了临界资源,因此,应确保临界区代码尽可能少,且停留在临界区的时间要尽量短。

临界区调度原则:

  • 临界区代码量尽可能少,减少进程(线程)串行时间

  • 一次值允许一个进程(线程)进入

  • 已有进程(线程)进入临界区,其他进程(线程)需等待或者被挂起

  • 进程(线程)进入临界区应能够尽快退出,不长能时间停留

  • 高优先级的进程(线程)在适当时候主动退出临界区,防止其他进程(线程)饥饿


2.2 临界资源访问原则

  临界资源的访问必须互斥进行,否则会导致数据异常。即是当临界资源被一个进程(线程)占用时,另一个申请临界资源的进程(线程)会被阻塞,直到其所申请的临界资源被释放。比如A在使用打印机,如果打印机机没有互斥机制,此时又响应B的打印请求,那么打印出来的数据肯定是不符合预期的,只有A的请求打印完成后才执行B的打印才能得到正确的打印结果。对于临界资源访问,一般分为几个步骤:

【1】进入区过程:检查资源是否可访问

【2】临界区过程:访问资源,标记资源已被占用

【3】退出区过程:退出访问,清除资源占用标识


3 互斥与同步

3.1 互斥

   互斥指的是多个进程(线程)不能同时访问临界资源,一个进程(线程)访问临界资源时,其他进程(线程)必须等等其访问完并退出后才能访问。

在这里插入图片描述

互斥模型

互斥特性:

  • 唯一性
  • 排他性

互斥场景:

  • 文件读写模型,多个读或者写线程访问文件
  • 总线访问模型,多个线程访问一个总线(spi、i2c、usb)
  • 外设访问模型,多个线程访问一个外部设备(flash、sensor、adc)

3.2 同步

  同步指的是多个进程(线程)间必须严格按照一种先后顺序的原则访问临界资源,存在一种依赖的关系,只有A执行了,B才能执行,是一个“生产者—消费者”模型。

在这里插入图片描述

同步模型

同步特性:

  • 唯一性
  • 排他性
  • 顺序性

同步场景:

  • 文件读写模型,写文件线程与读文件过程
  • 数据通信模型,数据接收线程与数据处理线程

3.3 互斥与同步的联系

  从互斥和同步的特性可看出,互斥和同步都具备“唯一性”和“排他性”;不同的是,互斥可以是无序,同步还具有一个“顺序性”,带有依赖关系。可以认为,互斥是特殊的同步;同步是更为复杂的互斥。即是,同步一定是互斥的,但互斥不一定是同步的。


3 POSIX线程互斥与同步机制

  POSIX线程标准和POSIX标准提供了几种线程互斥与同步(线程间通信)机制,关于每一种机制的含义、特性、应用场景、函数API及使用规则和使用方法,在后面文章针对性地一一描述。

POSIX线程标准:

【1】互斥锁(Mutex)

【2】读写锁(Read/Write lock)

【4】自旋锁(Spin lock)

【5】屏障(Barrier)

【6】条件变量(Condition variable)

POSIX标准:

【1】信号量(Seamphore)

【2】消息队列(Message queue)


4 参考文章

【1】同步和互斥

猜你喜欢

转载自blog.csdn.net/qq_20553613/article/details/106214865
今日推荐