2024.2.23
1.1.1 信号默认、捕获、忽略处理(普通信号)
#include <myhead.h>
void handler(int signo)
{if(signo==SIGINT){printf("用户键入 ctrl+c\n");}
}
int main(int argc, const char *argv[])
{//忽略信号if(signal(SIGINT,SIG_IGN)==SIG_ERR){perror("signal error");return -1;}/*//默认处理信号if(signal(SIGINT,SIG_IGN)==SIG_ERR){perror("signal error");return -1;}//捕获信号if(signal(SIGINT,handler)==SIG_ERR){perror("signal error");return -1;}*/while(1){printf("123456\n");sleep(1);}return 0;
}
1.1.2 SIGCHLD回收僵尸进程
#include <myhead.h>
void handler(int signo)
{if(signo==SIGCHLD){while(waitpid(-1,NULL,WNOHANG)>0);//waitpid(-1,NULL,WNOHANG);}
}
int main(int argc, const char *argv[])
{//捕获信号if(signal(SIGCHLD,handler)==SIG_ERR){perror("signal error");return -1;}//创建僵尸进程for(int i=0;i<5;i++){if(fork()==0){sleep(1);exit(EXIT_SUCCESS);}}while(1);return 0;
}
1.1.3 模拟出牌
#include <myhead.h>//信号处理函数
void handler(int signo)
{if(signo==SIGALRM){printf("系统为您出了一张牌\n");alarm(5);}
}
int main(int argc, const char *argv[])
{//捕获SIGALRM信号if(signal(SIGALRM,handler)==SIG_ERR){perror("signal error");return -1;}alarm(5); //启动定时器//出的牌char ch=0;while(1){scanf("%c",&ch);getchar();printf("你出的牌为:%c\n",ch);alarm(5);}return 0;
}
1.1.4 发送信号函数
#include <myhead.h>void hander(int signo)
{if(signo==SIGUSR1){printf("大清亡了\n");raise(SIGKILL);}
}
int main(int argc, const char *argv[])
{//发送信号if(signal(SIGUSR1,hander)==SIG_ERR){perror("signal error");return -1;}//创建进程pid_t pid=fork();if(pid>0){//父进程while(1){printf("这是朕的江山\n");sleep(1);}}else if(pid==0){//子进程sleep(3);printf("我才是真命天子\n");kill(getppid(),SIGUSR1);while(1){printf("现在是我的了\n");sleep(1);}}else{perror("pid error");return -1;}return 0;
}
1.2 消息队列
msgsnd.c:
#include <myhead.h>//消息队列结构体
struct msgbuf
{long mtype;char mtest[1024];
};
//宏表示消息正文的大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const char *argv[])
{//创建 key 值key_t key=0;if((key=ftok("/",'k'))==-1){perror("ftok error");return -1;}printf("fork success key=%#x\n",key);//根据key值创建消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}printf("msgget success msqid=%#x\n",msqid);//定义一个消息struct msgbuf sbuf;while(1){//清空正文的容器bzero(sbuf.mtest,sizeof(sbuf.mtest));printf("请输入当前消息的类型:");scanf("%ld",&sbuf.mtype);getchar(); //吸收垃圾字符printf("请输入消息正文:");fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);sbuf.mtest[strlen(sbuf.mtest)-1]='\0';//将消息存放到队列中msgsnd(msqid,&sbuf,MSGSIZE,0);printf("发送成功\n");if(strcmp(sbuf.mtest,"quit")==0){break;}}return 0;
}
msgrcv.c:
#include <myhead.h>//消息队列结构体
struct msgbuf
{long mtype;char mtest[1024];
};
//宏表示消息正文的大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const char *argv[])
{//创建 key 值key_t key=0;if((key=ftok("/",'k'))==-1){perror("ftok error");return -1;}printf("fork success key=%#x\n",key);//根据key值创建消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}printf("msgget success msqid=%#x\n",msqid);//定义一个消息struct msgbuf rbuf;while(1){//清空正文的容器bzero(rbuf.mtest,sizeof(rbuf.mtest));//从消息队列中读取一个消息msgrcv(msqid,&rbuf,MSGSIZE,0,0);printf("收到的消息为:%s\n",rbuf.mtest);if(strcmp(rbuf.mtest,"quit")==0){break;}}//删除消息队列if(msgctl(msqid,IPC_RMID,NULL)!=0){perror("msgctl error");return -1;}return 0;
}
作业2:使用消息队列完成两个进程间相互通信
msgsnd.c:
#include <myhead.h>//定义一个消息类型
struct msgbuf
{long mtype;char mtest[1024];
};//宏表示消息正文大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)/*****************************主程序***********************/
int main(int argc, const char *argv[])
{//1、创建key值key_t key=0;if((key=ftok("/",'k'))==-1){perror("ftok error");return -1;}//根据key值创建一个消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}//创建一个子进程pid_t pid=fork();if(pid>0){//父进程向消息队列中写入类型为1的消息正文//定义一个消息struct msgbuf sbuf;sbuf.mtype=1;while(1){//清空容器bzero(sbuf.mtest,sizeof(sbuf.mtest));printf("发送的消息:");fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);sbuf.mtest[strlen(sbuf.mtest)-1]='\0';//将消息存放到消息队列msgsnd(msqid,&sbuf,MSGSIZE,0);printf("发送成功\n");if(strcmp(sbuf.mtest,"quit")==0){break;}}wait(NULL); }else if(pid==0){//子进程从消息队列中取出类型为2的消息正文//定义一个消息struct msgbuf rbuf;while(1){//清空容器bzero(rbuf.mtest,sizeof(rbuf.mtest));//从消息队列中读取类型为2的消息正文msgrcv(msqid,&rbuf,MSGSIZE,2,0);printf("收到的消息为:%s\n",rbuf.mtest);if(strcmp(rbuf.mtest,"quit")==0){break;}}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}
msgrcv.c:
#include <myhead.h>//定义一个消息类型
struct msgbuf
{long mtype;char mtest[1024];
};//宏表示消息正文大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)/*****************************主程序***********************/
int main(int argc, const char *argv[])
{//1、创建key值key_t key=0;if((key=ftok("/",'k'))==-1){perror("ftok error");return -1;}//根据key值创建一个消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}//创建一个子进程pid_t pid=fork();if(pid>0){//父进程从消息队列中取出类型为1的消息正文//定义一个消息struct msgbuf rbuf;while(1){//清空容器bzero(rbuf.mtest,sizeof(rbuf.mtest));//从消息队列中读取类型为1的消息正文msgrcv(msqid,&rbuf,MSGSIZE,1,0);printf("收到的消息为:%s\n",rbuf.mtest);if(strcmp(rbuf.mtest,"quit")==0){break;}}wait(NULL);}else if(pid==0){//子进程向消息队列中写入类型为2的消息正文//定义一个消息struct msgbuf sbuf;sbuf.mtype=2;while(1){//清空容器bzero(sbuf.mtest,sizeof(sbuf.mtest));printf("发送的消息:");fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);sbuf.mtest[strlen(sbuf.mtest)-1]='\0';//将消息存放到消息队列msgsnd(msqid,&sbuf,MSGSIZE,0);printf("发送成功\n");if(strcmp(sbuf.mtest,"quit")==0){break;}}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}
相关文章:
2024.2.23
1.1.1 信号默认、捕获、忽略处理(普通信号) #include <myhead.h> void handler(int signo) {if(signoSIGINT){printf("用户键入 ctrlc\n");} } int main(int argc, const char *argv[]) {//忽略信号if(signal(SIGINT,SIG_IGN)SIG_ERR){perror("signal er…...
PHP实现分离金额和其他内容便于统计计算
得到的结果可以粘贴到excel计算 <?php if($_GET["x"] "cha"){ $tips isset($_POST[tips]) ? $_POST[tips] : ; $pattern /(\d\.\d|\d)/; $result preg_replace($pattern, "\t\${1}\t", $tips); echo "<h2><strong>数…...
基础数据结构和算法《》
递归 1.递归应该一种比较常见的实现一些特殊代码逻辑时需要做的,但常常也是最绕的一种方式,在解释递归 之前,我们用循环和递归来做个比较1.1.如果你打开一扇门后,同样发现前方也有一扇们,紧接着你又打开下一扇门...直…...
[设计模式Java实现附plantuml源码~行为型]对象间的联动~观察者模式
前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很…...
vue3+js 实现记住密码功能
常见的几种实现方式 1 基于spring security 的remember me 功能 localStorage 除非主动清除localStorage 里的信息 ,不然永远存在,关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…...
基于单片机的太阳能电池板自动跟踪系统的研究
摘要 伴随着人类社会的发展,人口基数越来越大,电量消耗巨大,传统发电原 料污染环境的同时,可用量日益减少,给人类未来生产生活带来了一定的威胁, 因而解决日益剧增的用电量,寻求一种新能源显得极其重要。论文正是基于此 背景下,针对当前太阳能电池板采光率低、自动化水…...
React 模态框的设计(二)
自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求,比如关于弹窗,每个应用都会用到,但是有时我们使用的框架中提供的弹窗功能也是功能有限,无法满足我们的应用需求,今天…...
操作符详解3
✨✨ 欢迎大家来到莉莉的博文✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 前面我们已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作 符,今天继续介绍一部分。 目录 1.操作符的分类 2…...
【C语言基础】:操作符详解(一)
文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…...
通俗易懂分析:Vite和Webpack的区别
1、对项目构建的理解 先从浏览器出发, 浏览器是由浏览器内核和JS引擎组成;浏览器内核编译解析html代码和css代码,js引擎编译解析JavaScript代码;所以从本质上,浏览器只能识别运行JavaScript、CSS、HTML代码。 而我们在…...
OpenCart程序结构与业务逻辑
一、程序业务逻辑说明 在 OpenCart 中,index.php 文件是整个应用程序的入口文件,它负责初始化应用程序并调度请求。以下是 index.php 文件加载执行的流程: 1. **设置路径常量:** - index.php 首先定义了一些重要的路径常量&…...
软件License授权原理
软件License授权原理 你知道License是如何防止别人破解的吗?本文将介绍License的生成原理,理解了License的授权原理你不但可以防止别人破解你的License,你甚至可以研究别人的License找到它们的漏洞。喜欢本文的朋友建议收藏+关注,方便以后复习查阅。 什么是License? 在…...
C/C++实现老鼠走迷宫
老鼠形象可以辨认,可以用上下左右操纵老鼠;正确检测结果,若老鼠在规定的时间内走到粮仓,提示成功,否则提示失败。代码分为3个文件:main.cpp、play.h、play.cpp。 main.cpp: #include <iostream> #include <…...
[Linux]文件基础-如何管理文件
回顾C语言之 - 文件如何被写入 fopen fwrite fread fclose fseek … 这一系列函数都是C语言中对文件进行的操作: int main() {FILE* fpfopen("text","w");char str[20]"write into text";fputs(str,fp);fclose(fp);return 0; }而上…...
bat 查找文件所在
脚本 在批处理文件(.bat)中查找文件所在的目录,你可以使用dir命令结合循环和条件语句来实现。以下是一个简单的示例,演示如何在批处理文件中查找指定文件并输出其所在目录: echo off setlocal enabledelayedexpansio…...
程序员的守护神:为何电脑永不熄灭?
在这个信息时代,程序员成了推动社会进步的“隐形英雄”。他们通宵达旦,手指在键盘上跳跃,创造出一个个令人惊叹的数字世界。有趣的是,你可能注意到了一个现象:程序员似乎总是不关电脑。这并非他们对电脑上瘾࿰…...
Kafka快速实战以及基本原理详解
Kafka快速实战以及基本原理详解 基本概念 Kafka是一个分布式、支持分区、多副本,基于ZK的分布式消息系统,最大的特性就是可以实时的处理大量数据以满足各种需求场景,比如Hadoop的批处理系统、低延迟的实时系统、Storm/Spark流式处理引擎、日…...
微信小程序(4)- 事件系统和模板语法
1. 事件系统 1.1 事件绑定和事件对象 小程序中绑定事件与在网页开发中绑定事件几乎一致,只不过在小程序不能通过 on 的方式绑定事件,也没有 click 等事件,小程序中绑定事件使用 bind 方法,click 事件也需要使用 tap 事件来进行代…...
【Java多线程】对线程池的理解并模拟实现线程池
目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多,例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是:(提高效率) 1…...
python连接mysql数据库
连接MySQL数据库,通常我们会使用Python的mysql-connector-python库。下面是一个基本的示例来展示如何使用Python连接到MySQL数据库。 首先,确保你已经安装了mysql-connector-python库。如果没有,你可以使用pip来安装它: pip ins…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
