代码改变世界

Linux -- 进程间通信之信号量

2019-11-26 02:13  陈心朔  阅读(234)  评论(0编辑  收藏  举报

基本概念简述

多个线程同时访问一个共享数据,很可能造成恶劣的后果;为了保证数据访问资源的正确性和安全性,需要对线程进行"同步"
(Linux下所有的执行实体都称为任务(task),每个任务类似于单线程的进程,共享了同一个内存空间的多个任务构成了一个进程)
 

  • 同步
    指在一个线程对数据访问未结束的时候,其他线程不得访问同一个数据,将对数据的访问原子化
     
  • 原子操作
    不可分割,不会被线程调度打断的操作
    (一个程序在运行的过程中可能被优先级更高的线程中断,而有些操作是不可中断的,不然会出现无法还原的后果,这时候操作系统就需要原子操作)

线程同步

同步最常用的方式"锁",每一个线程访问数据或资源前首先要获取锁,并在访问结束后释放锁;在锁被占用时试图获取锁,线程会进入等待,直到锁重新可用
二元信号量是最简单的一种锁,适合被一个线程独占访问的资源。它只有两种状态,占用和非占用;当一个线程获取锁后,其他线程试图获取锁将进入等待,直到该锁被释放。
 
互斥量类似于二元信号量,资源同时只允许一个线程访问,不同的是信号量在整个系统中允许任何线程获取并释放,即信号量可以被系统中一个线程获取,然后由另一个线程释放它;而互斥锁要求哪个线程获取互斥量,这个线程就要负责释放这个锁,其他线程释放该互斥量是无效的

  • 临界资源
    一次仅允许一个进程访问的资源称为临界资源,通常用互斥量控制临界资源的访问
     

P(测试)/ V(增加)操作

对于允许多个线程并发访问的锁成为多元信号量,简称信号量,一个初始值为N的信号量允许N个线程同时访问,线程访问资源首先获取信号量,进行如下操作(P):

  1. 将信号量的值减 1
  2. 如果信号量的值小于 0,则进入等待

 
访问完资源后,线程释放信号量,进行如下操作(V):

  1. 将信号量的值加 1
  2. 如果信号量的值小于 1,唤醒一个等待中的线程