Linux学习笔记12 - 进程间通信(IPC)(三)

154 阅读3分钟

信号量

  • 信号量(semaphore):其是用来解决进程之间的同步与互斥问题的一种进程之间通信机制,包括一个称为信号量的变量和在该信号量下等待资源的进程等待队列,以及对信号量进行的两个原子操作(PV 操作)。其中信号量指代的是某一种资源,取一个非负的整型值(sem_val>=0);其值指的是当前可用的该资源的数量,若它等于 0 则意味着目前没有可用的资源

    • 同步:处理竞争就是同步,安排进程执行的先后顺序就是同步,每个进程都有一定的个先后执行顺序。

    • 互斥:互斥访问不可共享的临界资源,同时会引发两个新的控制问题(互斥可以说是特殊的同步)。

    • 竞争:当并发进程竞争使用同一个资源的时候,我们就称为竞争进程。

    • 临界资源:其是在同一个时刻只允许有限个(通常只有一个)进程可以访问使用(读写操作)的资源,通常包括硬件资源(处理器、内存、存储器以及其他外围设备等和软件资源(共享代码段,共享结构和变量等)。 访问临界资源的代码叫做临界区

    • P 操作:如果有可用的资源(信号量值:sem_val>0),则占用一个资源(sem_val--,进入临界区代码);如果没有可用的资源(sem_val = 0),则被阻塞直到系统将资源分配给该进程(要想访问就必须等待(具体怎么等还有说法,比如忙等待或者睡眠))。

    • V 操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞进程。如果没有进程等待它,则释放一个资源(sem_val++)。

    • 原子操作是指当多个线程试图修改同一个信号量的值时,各线程修改值的过程不会互相干扰。例如信号量的初始值为 1,此时有 2 个线程试图对信号量做“加 1”操作,则信号量的值最终一定是 3,而不会是其它的值。反之若不以“原子操作”方式修改信号量的值,那么最终的计算结果还可能是 2(两个线程同时读取到的值为 1,各自在其基础上加 1,得到的结果即为 2)。

  • 二值信号量(或称二进制信号量):其是指只有0和1两种信号值的特殊信号量。

  • 信号量相关操作

    • (1)创建信号量或获得在系统已存在的信号量,此时需要调用 semget() 函数。不同进程通过使用同一个信号量键值来获得同一个信号量。
    • (2)初始化信号量,此时使用 semctl() 函数的 SETVAL 操作。当使用二维(值)信号量时,通常将信号量初始化为 1。
    • (3)进行信号量的 PV 操作,此时调用 semop() 函数。这一步是实现进程之间的同步和互斥的核心工作部分。
    • (4)如果不需要信号量,则从系统中删除它,此时使用 semclt() 函数的 IPC_RMID 操作。此时需要注意,在程序中不应该出现对已经被删除的信号量的操作。
  • 信号量实现原理及机制信号量及其使用和实现(超详细)