当前位置: 首页 > news >正文

LINUX系统编程:信号量

目录

1.信号量理论

2.信号量原理

3.信号量的接口


1.信号量理论

信号量是进程之间通信的一种。

信号量可以在多执行流下对,共享资源进行保护(例:共享内存本身是是一种共享资源,但是本身是不带协同机制的,这样就会出现数据不一致的问题,写端想写"hello world",但是在写端写到hello时,读端就把数据读走了,造成了数据不一致)。

互斥:在访问公共资源时,只能有一个进程访问。

同步:在访问资源安全的前提下,各进程按一定顺序,并发访问资源。

临界区:访问临界资源的那些代码,就是临界区,保护临界资源本质就是保护临界区。

原子性:执行一个动作只有两种状态,一种是成功,一种是未开始,也就是说这个动作是不能在被切分的。

2.信号量原理

信号量是一种资源预定机制,只要预定了,资源在未来一定是该进程的。

这是一块共享内存,这个内存被分成了12个区域,每个进程只会访问一小块区域。

每个小区域都有自己的编号,当一个执行流想使用小块资源时必须,申请对应的编号,然后才能让问对应的小区域,使用完之后还要将编号还回去,这样保证每一块的小资源都是互斥访问的,大块的资源就是多个进程同步访问的。

信号量的本质就是一个计数器

信号量申请成功,p操作对计数器做--

访问资源

释放信号量,v操作对计数器做++】

3.信号量的接口

semget

semget系统调用接口,返回system v类型,与参数key相关联的信号量标识符集。semget可能获得一个先前已经创建好的信号量,或者创建一个新的集和。

key:是个密钥,通过ftok创建,保证多个进程使用同一个密钥就可以看见同一块资源。

nsems:创建多少个信号量。

semflg: O_CREAT不存在就创建,存在就返回对应的信号量标识符集。

                O_CREAT|O_EXCL不存在就创建,存在就出错。

semctl

semctl执行由参数cmd指定的控制操作,在参数semid信号量标识符集,或者在该信号量标识符集的semunm个参数执行操作。

semop

对由semid指示的信号量集中选定的信号量执行操作。由sops指向的数组中的nsops个元素,每个都是一个结构体,用于指定在单个信号量上执行的操作。该结构体的成员类型为struct sembuf,包含以下成员:

sem_num:信号量值

semop:信号量操作

sem_flag:信号量标志。

ipc资源的共性

我们发现无论是信号,消息队列,共享内存,描述管体ipc资源的结构体的第一个参数都是ipc_perm。

先说结论,这么设计是为了实现一种c语言的多态,方便对ipc资源的管理,也可以理解为,ipc_perm 是基类,其余的结构体成员是派生类的部分。

这么做是为了方便管理ipc资源,这样就可以将ipc资源进行统一的管理,这样对ipc资源的管理就变成了对ipc数组的增删查改。

是怎么做的呢?

结构体的地址就是,结构体内第一个元素的地址,直接强转成为对应的类型就可以。

(msg_queue*)ipc[1]

(sem_arry*)ipc[2]

(shmid_kernel*)ipc[3]

如何知道是什么类型呢

在ipc_perm这个结构体中,存在一个成员变量mode,里面储存的是ipc资源的类型

#define IPC_TYPE SHM 0x1
#define IPC_TYPE MSG (0x1<<1)
#define IPC_TYPE SEM (0x1<<2)shmid_kernel* (ipc_perm * p)
{if(p->mode & IPC_TYPE SHM){return (shmid_kernel*)p;}else{return NULL;}}

相关文章:

  • 最新扣子(Coze)使用指南更新:如何导入扣子插件,完全免费Coze教程
  • JavaScript函数进阶学习
  • 0基础认识C语言(理论知识)
  • 算法课程笔记——计数原理
  • 直流电机工作原理与控制电路解析
  • 汇编原理(三)编程
  • Android bw_costly_<iface>链
  • TypeScript算法每日一题:两数之和(1)
  • 计算机网络介绍
  • 09Linux GDB学习笔记
  • ctfshow jwt web入门
  • 【前端】vue+element项目中select下拉框label想要显示多个值多个字段
  • 自然语言处理(NLP)—— 神经网络语言处理
  • NPN与PNP的基础知识介绍
  • 使用git将本地文件上传到仓库+git常用指令
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 自己简单写的 事件订阅机制
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • cookie和session
  • CSS魔法堂:Absolute Positioning就这个样
  • express + mock 让前后台并行开发
  • IP路由与转发
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JAVA多线程机制解析-volatilesynchronized
  • Just for fun——迅速写完快速排序
  • k8s 面向应用开发者的基础命令
  • maven工程打包jar以及java jar命令的classpath使用
  • Netty源码解析1-Buffer
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Redis中的lru算法实现
  • scala基础语法(二)
  • STAR法则
  • vue 个人积累(使用工具,组件)
  • 飞驰在Mesos的涡轮引擎上
  • 今年的LC3大会没了?
  • 事件委托的小应用
  • 通过几道题目学习二叉搜索树
  • 异步
  • # 数论-逆元
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #include<初见C语言之指针(5)>
  • #php的pecl工具#
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (13)Hive调优——动态分区导致的小文件问题
  • (2)MFC+openGL单文档框架glFrame
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (顺序)容器的好伴侣 --- 容器适配器
  • (五)MySQL的备份及恢复
  • .describe() python_Python-Win32com-Excel
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .Net面试题4
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)