Linux Day13 ---信号量
一、信号量
1.1 一些概念
用来管理对资源的访问
一个特殊的变量,只允许对它进行等待(wait)和发送信号(signal),代表可用资源个数,
取0,1 二值信号量
取 3,5 计数信号量
p操作:原子减一,代表获取资源,可能阻塞
v操作:原子加一 代表释放资源,不会阻塞
临界区:真正执行数据更新的代码需要独占式地执行(即临界资源所在位置)
临界资源:只有一个进程可以进入这个临界代码并拥有对资源独占式的访问权(同一时刻只能执行一个代码)

1.2 信号量的机制
#include<sys/sem.h>
1.2.1 semget函数
作用:创建一个新信号量或取得一个已有信号量的键;
定义:int semget(key_t key,int num_sems,int sem_flags);
key:整数值,不相关的进程可以通过它访问同一个信号量。
num_sems:参数指定需要的信号量数目,他几乎总是取值为1.
sem_flag:类似于文件的访问权限,一般用IPC_CREAT:创建一个新信号量,即使给出的键是一个已有信号量的键,也不会产生错误。一般还要用到IPC_EXCL:确保创建出一个新的唯一的信号量,如果信号量已存在,将返回错误。
这个函数在成功时返回一个整数,即其他信号量函数将用到的信号量标识符。
如果失败返回-1。
1.2.2 semop函数
作用:semop()对信号量进行改变,做 P 操作或者 V 操作
1.2.3 实现上述函数
头文件 sem.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<sys/sem.h>
union semun{int val;
};
void sem_init();
void sem_p();
void sem_v();
void sem_destroy(); #include "sem.h"
static int semid=-1;
void sem_init()
{semid=semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);//创建一个新的信号量if(semid==-1){semid=semget((key_t)1234,1,0600);//表明这个信号量是已存在的信号量if(semid==-1){printf("semget err\n");//这个信号量创建失败}}else{union semun a;a.val=1;if(semctl(semid,0,SETVAL,a)==-1)//初始化该信号量{printf("semctl err\n");}}
}
void sem_p()
{struct sembuf sem;sem.sem_flg=SEM_UNDO;sem.sem_num=0;sem.sem_op=-1;//p操作if(semop(semid,&sem,1)==-1){printf("sem_p err\n");}
}
void sem_v()
{struct sembuf sem;sem.sem_flg=SEM_UNDO;sem.sem_num=0;sem.sem_op=1;//v操作if(semop(semid,&sem,1)==-1){printf("sem_v err\n");}
}
void sem_destroy()
{if(semctl(semid,0,IPC_RMID)==-1)//删除该信号量{printf("sem_destory err\n");}
} 1.2.4 举个栗子
step 1:不引入信号量
step 2:引入信号量

定义一个信号量初始化值为1 ,当a进程拿到这个信号量,就进行p操作,让这个信号量为0,此时b进程没有可以使用的信号量就会等待a进程结束,a进程结束后会v操作,让信号量为1 ,此时b进程就可以执行,依次循环下去。
a.c
#include"sem.h"
int main()
{sem_init();//for(int i = 0; i < 5; i++){//psem_p();printf("a");fflush(stdout);int n = rand() % 3;sleep(n);printf("a");fflush(stdout);sem_v();n = rand() % 3;sleep(n);}sem_destroy();return 0;
}
b,c
#include"sem.h"
int main()
{sem_init();//for(int i = 0; i < 5; i++){//psem_p();printf("b");fflush(stdout);int n = rand() % 3;sleep(n);printf("b");fflush(stdout);sem_v();n = rand() % 3;sleep(n);}return 0;
}
step3:结果

此时a和b各是成对出现
二、共享内存
2.1 一些概念
2.2 共享内存的机制
2.2.1 shmget()
shmget()成功返回共享内存的 ID, 失败返回-1
2.2.2 shmat()
2.2.3 shmdt()
shmdt()断开当前进程的 shmaddr 指向的共享内存映射2.2.4 shmctl()
2.3 举个栗子
step 1:不加信号量

step 2:使用信号量

step 3:代码实现
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include "sem.h"int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);if ( shmid == -1 ){printf("shmget err\n");exit(1);}char* s = (char*)shmat(shmid,NULL,0);if ( s == (char*)-1) {printf("shmat err\n");exit(1);} sem_init();while( 1 ){printf("input\n");char buff[128] = {0};fgets(buff,128,stdin);sem_p(SEM1);strcpy(s,buff);sem_v(SEM2);if ( strncmp(buff,"end",3) == 0){break;}}shmdt(s);
}
test.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include "sem.h"int main()
{int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);if ( shmid == -1 ){printf("shmget err\n");exit(1);}char * s = (char*)shmat(shmid,NULL,0);if ( s == (char*)-1){printf("shmat err\n");exit(1);}sem_init();while( 1 ){sem_p(SEM2);if ( strncmp(s,"end",3) == 0 ){break;}printf("read:%s\n",s);sem_v(SEM1);}shmdt(s);shmctl(shmid,IPC_RMID,NULL);sem_destroy();
}
相关文章:
Linux Day13 ---信号量
一、信号量 1.1 一些概念 用来管理对资源的访问 一个特殊的变量,只允许对它进行等待(wait)和发送信号(signal),代表可用资源个数, 取0,1 二值信号量 取 3,5 计数信号量 p操作:原子减一,代表获取资源,可能阻塞 v…...
《动手学深度学习 Pytorch版》 4.10 实战Kaggle比赛:预测比赛
4.10.1 下载和缓存数据集 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载一个…...
jQuery补充
文章目录 简介安装语法选择器元素选择器#id 选择器.class 选择器事件常用事件方法 效果显示隐藏淡入淡出滑动动画停止动画获取内容和属性添加元素删除元素操作css父辈 💛💛孔子云:温故而知新,可以为师矣💛💛…...
goaccess 日志分析 nginx
分析命令: goaccess -a -d -f /mnt/winshare/access-2023070112.log -p goaccess.conf -o /mydata/nginx/html/2023070112_new.html分析日志时的参数 goaccess使用参数详解-a 开启 UserAgent 列表。开启后会降低解析速度 -c 在程序开始运行时显示 日志/日期 配…...
认养一头牛———众筹+合伙人商业模式解析
2016年成立以来,认养一头牛致力于打造数字化乳业第一品牌,只为一杯好牛奶。公司在创立三年内完成了10个亿销售目标,被业界称为新消费品牌黑马,一举闯入互联网新消费梯队的视线。未来三年,认养一头牛将着力打造全国最大…...
前端面试的话术集锦第 11 篇:高频考点(React和Vue两大框架)
这是记录前端面试的话术集锦第十一篇博文——高频考点(React和Vue两大框架),我会不断更新该博文。❗❗❗ React 和Vue应该是国内当下最火热的前端框架。当然,Angular也是一个不错的框架,但是这个产品,国内使用的人很少,因而,框架的章节中不会涉及到Angular的内容。 这…...
前端js下载zip文件异常问题解决
目录 一,本文解决问题如下 二,原下载代码 1,ajax get 下载文件 2,下载异常图: 三,成功下载的 1, JQuery 实现文件下载xhr 2,图例 引言: 本人使用的ajax 下载&…...
深度学习面试八股文(2023.9.06)
一、优化器 1、SGD是什么? 批梯度下降(Batch gradient descent):遍历全部数据集算一次损失函数,计算量开销大,计算速度慢,不支持在线学习。随机梯度下降(Stochastic gradient desc…...
Linux入门-网络基础|网络协议|OSI七层模型|TCP/IP五层模型|网络传输基本流程
文章目录 一、网络基础 二、网络协议 1.OSI七层模型 2.TCP/IP五层(或四层)模型 三、网络传输基本流程 1.网络传输流程图 2.数据包封装和分用 四、网络中的地址管理 1.IP地址 2.MAC地址 一、网络基础 网络发展最初是独立模式,即计算…...
docker系列(2) - 常用命令篇
文章目录 2. docker常用命令2.1 参数说明(tomcat案例)2.2 基本命令2.3 高级命令2.4 其他 2. docker常用命令 2.1 参数说明(tomcat案例) 注意如果分成多行,\后面不能有空格 # 拉取运行 docker run \ -d \ -p 8080:8080 \ --privilegedtrue \ --restartalways \ -m…...
Debian11安装MySQL8.0,链接Navicat
图文小白教程 1 下载安装MySQL1.1 从MySQL官网下载安装文件1.2 安装MySQL1.3 登录MySQL 2 配置Navicat远程访问2.1 修改配置2.2 Navicat 连接 end: 卸载 MySQL 记录于2023年9月,Debian11 、 MySQL 8.0.34 1 下载安装MySQL 1.1 从MySQL官网下载安装文件 打开 MySQ…...
vue项目中使用特殊字体的步骤
写在前面 在项目中使用特殊字体,需要注意,所使用的特殊字体是否被允许商用或是个人开发,以及如何使用,切记不要侵权。 首先需要在对应字体网站下载字体文件,取出里面后缀名为.ttf的文件 然后把该文件放到src -> ass…...
激光雷达检测负障碍物(附大概 C++ 代码)
检测效果如图,红色是正负的障碍物点: 障碍物根据其相对于地面的高度可以分为两类:正向障碍物和负向障碍物。在室外环境中,负障碍物是沟渠、悬崖、洞口或具有陡峭负坡度的地形,可能会造成安全隐患。 不慎通过道路坑洼处…...
【每日一题】9.13 PING是怎么工作的?
PING命令的作用是什么? PING命令是计算机网络中常用的命令之一,它的作用是测试两台计算机之间的连通性以及测量数据包往返的时间。 PING命令的工作原理是什么? PING命令的工作原理涉及到ICMP(Internet Control Message Protocol)和网络协议栈的操作: 1.发送ICMP …...
【Python百日进阶-Web开发-Peewee】Day279 - SQLite 扩展(四)
文章目录 12.2.10 class FTSModel 12.2.10 class FTSModel class FTSModel与FTS3 和 FTS4 全文搜索扩展VirtualModel一起使用的子类。 FTSModel 子类应该正常定义,但是有几个注意事项: 不支持唯一约束、非空约束、检查约束和外键。字段索引和多列索引…...
Postman接口压力测试 ---- Tests使用(断言)
所谓断言,主要用于测试返回的数据结果进行匹配判断,匹配成功返回PASS,失败返回FAIL。 下图方法一,直接点击右侧例子函数,会自动生成出现在左侧窗口脚本,只需修改数据即可。 方法二:直接自己写脚…...
nvue文件中@click.stop失效
在nvue文件中在子元素使用click.stop失效,父元素的事件触发了 在uniapp开发中nvue文件是跟vue文件是不一样的,就比如click.stop阻止点击事件继续传播就失效了,这时我们需要在子元素事件中添加条件编译,这样就会解决这个问题 // …...
【微信小程序开发】宠物预约医疗项目实战-开发功能介绍
【微信小程序开发】宠物医院项目实战-开发功能介绍 前言 本项目主要带领大家学习微信小程序开发技术,通过一个完整的项目系统的学习微信小程序的开发过程。鉴于一些同学对视频教学跟不上节奏,为此通过图文描述的方式,完整的将系统开发过程记…...
vue网页缓存页面与不缓存页面处理
在主路由页面 <template><div style"height: 100%"><!-- 缓存 --><keep-alive><router-view v-if"$route.meta.keepAlive"></router-view></keep-alive><!-- 不缓存 --><router-view v-if"!$rou…...
AI系统论文阅读:SmartMoE
提出稀疏架构是为了打破具有密集架构的DNN模型中模型大小和计算成本之间的连贯关系的——最著名的MoE。 MoE模型将传统训练模型中的layer换成了多个expert sub-networks,对每个输入,都有一层special gating network 来将其分配到最适合它的expert中&…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
