ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Linux信号量

2026/9/14 4:58:27 拓冰建站 浏览量
Linux信号量

📟作者主页:慢热的陕西人

🌴专栏链接:Linux

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

本博客主要内容感性认识了信号量,并且认识了IPC资源在操作系统内部是如何组织的

文章目录

  • Linux信号量
    • 1.互斥等四个概念
    • 2.认识信号量
    • 3.相关接口的认识
      • 3.1semget
      • 3.2ipcs -s
      • 3.3semctl
      • 3.4semop
    • 4.理解IPC
      • 4.1IPC资源是在内核中如何被组织和管理

Linux信号量

1.互斥等四个概念

首先我们进程通信的基础就是,让进程看到一个共同的资源:公共资源。

a.互斥

任何一个时刻,只允许一个执行流进行在共享资源的访问 – 加锁

b.临界资源

我们把任何时刻,只允许一个执行流访问的共享资源称为临界资源。

c.临界区

临界资源是要通过代码访问的,那么访问临界资源的代码就被称为临界区

d.原子性

要么不做,要么做完,只有两种确定状态的属性,原子性

2.认识信号量

任何技术都是有自己的应用场景的,首先我们通过一个买电影票的场景来感性的认识信号量。

首先我们看电影之前,我们都会先买票。

那么买票的本质功能:

  • 对座位资源的预定机制
  • 不会因为多方出去特定的座位资源,而导致冲突

那么放映厅是顶级的VIP放映厅,只有一个座位,那么同一时刻只有一个人能进行观看,并且他在观看的时候,其他人是不能去观看的,所以这就相当于我们之前所提到的互斥。

其实信号量本质就是一个计数器:用于描述资源数量的计数器count

在操作系统内部,任何一个执行流,向访问临界资源中的一个子资源的时候,不能直接访问。要先申请信号量资源,那么我们对应的信号量(count–),只要我们信号量成功,我就一定在未来能拿到一个子资源,叫做我们的申请临界资源成功(也有对应的申请失败,这时候进程就会阻塞挂起)。P操作

当我们的执行流进入自己的临界区,访问对应的临界资源

释放信号量资源 — 对应的信号量(count++) ---- 只要将计数器增加,就代表我们将对应的资源进行了归还。V操作

我们所有使用信号量的进程都是需要保证先看到信号量,那么信号量本质是一种共享资源,所以我们必须保证我们的count++count--是原子的!

总结下来,就是如下一幅图:进程通过执行代码来申请信号量

image-20231208081031212

  • 如何让两个进程看到同一个计数器(count)?

    这个需求是不是非常类似于我们进程通信的前提要求,让不同的进程看到同一份资源。

    所以信号量被归类到了进程间通信。

  • 假如信号量被设置为1呢?

    相当于这一份资源被独立使用了,也就是信号量的互斥功能。

3.相关接口的认识

3.1semget

用于获取信号量

参数:

  • key:和我们当时共享内存哪里的含义是一样的,用于操作系统区分对应的信号量;
  • nsems:用于表明申请信号量的个数;
  • semflg:和共享内存哪里的含义相同,可以输入对应的IPC_CREAT, IPC_EXCL等;

image-20231208085637121

3.2ipcs -s

用于查看当前系统中存在的信号量:我们这时候是没有的所以它没有任何显示

image-20231208090103368

3.3semctl

用于删除信号量的操作

  • semid:用户层面用于区分对应的信号量的的标识符;
  • semnum:要删除的信号量的个数;
  • cmd:要进行的操作;
  • …:可变参数

image-20231208090700269

对应的一些相关的结构体:

image-20231208091440341

3.4semop

对对应的信号量做操作

参数:

  • semid:表示我们要对哪一个信号量做操作
  • *sop:是一个结构体,需要我们去显式的定义具体包含如下的成员:
    image-20231208092026677
  • nsops:相当于是我们对应信号量数组的下标

image-20231208091823524

4.理解IPC

4.1IPC资源是在内核中如何被组织和管理

那么首先我们操作系统内部都是进行,先描述再组织;

先描述:讲共享内存,信号量,消息队列都用结构体描述起来。

再组织:操作系统用数组将这些对象组织起来

所以在操作系统内核所有的IPC资源都是以数组的方式进行管理的。

image-20231208101909899

  • 那么我们是如何进行访问的:

    首先我们进入ipc_id_arr[]数组内部,这个数组中全部存储的是struct ipc_perm*,假设这里我们要访问的是shmid_ds:那么我们就先将这个指针强转成对应的类型:((struct shmid_ds*)ipc_id_arr[n])->other...

以上的过程其实就是我们的多态,我们对应的stuct ipc_perm perm就是基类,

那么对应的struct shmid_ds,struct semid_dsstruct msqid_ds就是子类。

所以操作系统内部用不同的指针指向不同的对象,指向谁就访问谁。

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述