IO线程进程作业day6

news/发布时间2024/6/8 6:31:26

1> 将标准io文件IO的内容复习一遍

2> 进程线程的相关函数复习一遍

3> 将信号和消息队列的课堂代码敲一遍

1、处理普通信号

#include <myhead.h>	//定义信号处理函数
void handler(int signo)
{if(signo==SIGINT){puts("按下ctrl+c");}
}
int main(int argc, const char *argv[])
{//捕获SIGINT信号,处理方式 自定义函数if(signal(SIGINT,handler)==SIG_ERR){perror("signal error");return -1;}while(1){puts("赚小钱钱");sleep(1);}return 0;
}

2、 尝试捕获或忽略SIGKILL信号

#include <myhead.h>	int main(int argc, const char *argv[])
{//尝试忽略SIGKILL信号if(signal(SIGKILL,SIG_IGN)==SIG_ERR){perror("signal ERROR");return -1;}while(1){puts("明天放假");sleep(1);}return 0;
}

 3、使用SIGGHLD信号回收僵尸进程,当子进程退出后,子进程会向父进程发送一个SIGCHLD信号,表示子进程的退出

#include <myhead.h>	
//自定义信号处理方式
void handler(int signo)
{if(signo==SIGCHLD){while(waitpid(-1,NULL,WNOHANG)>0);//循环非阻塞的回收子进程的资源}
}
int main(int argc, const char *argv[])
{//将SIGCHLD信号和自定义函数绑定if(signal(SIGCHLD,handler)==SIG_ERR){perror("SIGNAL ERROR");return -1;}for(int i=0;i<10;i++)//创建10个僵尸进程{if(fork()==0){sleep(1);exit(EXIT_SUCCESS);//退出当前进程}}while(1);return 0;
}

 4、模拟斗地主出牌的案例

#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);//5秒不从终端输入牌,自动转到自定义函数中}return 0;
}

5、验证发送信号函数 

#include <myhead.h>	
//父进程收到信号处理任务
void handler(int signo)
{if(signo==SIGUSR1){puts("日薄西山,英雄迟暮\n父进程准备自杀");raise(SIGKILL);//父进程杀死自己}
}
int main(int argc, const char *argv[])
{//将SIGUSR1信号绑定if(signal(SIGUSR1,handler)==SIG_ERR){perror("SIGNAL ERROR");return -1;}pid_t pid=fork();if(pid>0){while(1){puts("父进程还或者");sleep(1);}}else if(pid==0){sleep(5);puts("子进程要独立了");kill(getppid(),SIGUSR1);//向父进程发生信号while(1){puts("富贵险中求");sleep(1);}}return 0;
}

6、 消息队列两个进程间的单向通信

user1代码:

#include <myhead.h>	//定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[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("ftok 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 =%d\n",msqid);//定义一个消息类型struct msgbuf sbuf;while(1){bzero(sbuf.mtext,sizeof(sbuf.mtext));//清空容器printf("请输入当前消息的类型:");scanf("%ld",&sbuf.mtype);getchar();//吸收回车printf("请输入正文内容:");fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);//从终端获取消息正文sbuf.mtext[strlen(sbuf.mtext)-1]=0;//向消息队列中存放消息msgsnd(msqid,&sbuf,MSGSIZE,0);printf("发送成功\n");if(strcmp(sbuf.mtext,"end")==0){break;}}return 0;
}

 usr2代码:

#include <myhead.h>	//定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[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("ftok 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 =%d\n",msqid);//定义一个消息类型struct msgbuf rbuf;while(1){bzero(rbuf.mtext,sizeof(rbuf.mtext));//清空容器//从消息队列中获取任意一个消息msgrcv(msqid,&rbuf,MSGSIZE,0,0);printf("收到的消息是类型%ld中的消息:%s\n",rbuf.mtype,rbuf.mtext);if(strcmp(rbuf.mtext,"end")==0){break;}}//删除消息队列if(msgctl(msqid,IPC_RMID,NULL)!=0){perror("msgctl error");return -1;}return 0;
}

4> 使用消息队列完成两个进程间相互通信

usr1代码:

#include <myhead.h>	//定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[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("ftok 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 =%d\n",msqid);pid_t pid=fork();//创建子进程if(pid>0)//父进程{struct msgbuf sbuf;sbuf.mtype=1;while(1){bzero(sbuf.mtext,sizeof(sbuf.mtext));//清空容器fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);//从终端获取消息正文sbuf.mtext[strlen(sbuf.mtext)-1]=0;//向消息队列中存放消息msgsnd(msqid,&sbuf,MSGSIZE,0);printf("usr1发送成功\n");if(strcmp(sbuf.mtext,"end")==0){kill(pid,SIGKILL);break;}}wait(NULL);}else if(pid==0)//子进程{struct msgbuf rbuf;while(1){bzero(rbuf.mtext,sizeof(rbuf.mtext));//清空容器//从消息队列中获取类型为2一个消息msgrcv(msqid,&rbuf,MSGSIZE,2,0);printf("收到的消息是类型%ld中的消息:%s\n",rbuf.mtype,rbuf.mtext);if(strcmp(rbuf.mtext,"end")==0){kill(getppid(),SIGKILL);break;}}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}

 usr2代码:

#include <myhead.h>	
///定义信号处理函数
void handler(int signo)
{if(signo == SIGCHLD){		wait(NULL);exit(EXIT_SUCCESS);}
}
//定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[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("ftok 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 =%d\n",msqid);	struct msgbuf rbuf;	struct msgbuf sbuf;sbuf.mtype=2;pid_t pid=fork();//创建进程if(pid>0)//父进程{signal(SIGCHLD,handler);while(1){bzero(sbuf.mtext,sizeof(sbuf.mtext));//清空容器fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);//从终端获取消息正文sbuf.mtext[strlen(sbuf.mtext)-1]=0;//向消息队列中存放消息:msgsnd(msqid,&sbuf,MSGSIZE,0);printf("usr2发送成功\n");if(strcmp(sbuf.mtext,"end")==0) {kill(pid,SIGKILL);break;}}	}else if(pid==0)//子进程{while(1){bzero(rbuf.mtext,sizeof(rbuf.mtext));//清空容器//从消息队列中获取类型为1一个消息msgrcv(msqid,&rbuf,MSGSIZE,1,0);printf("usr2收到的消息是类型%ld中的消息:%s\n",rbuf.mtype,rbuf.mtext);if(strcmp(rbuf.mtext,"end")==0){break;}}//删除消息队列if(msgctl(msqid,IPC_RMID,NULL)!=0){perror("msgctl error");return -1;}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}

思维导图:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/lsgf/3925.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

chatGPT 使用随想

一年前 chatGPT 刚出的时候&#xff0c;我就火速注册试用了。 因为自己就是 AI 行业的&#xff0c;所以想看看国际上最牛的 AI 到底发展到什么程度了. 自从一年前 chatGPT 火出圈之后&#xff0c;国际上的 AI 就一直被 OpenAI 这家公司引领潮流&#xff0c;一直到现在&#x…

创建型设计模式 - 原型设计模式 - JAVA

原型设计模式 一 .简介二. 案例三. 补充知识 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 一 .简介 原型模式提供了一种机制&#xff0c;可以将原始对象复制到新对象&#xff0…

突出最强算法模型——回归算法 !!

文章目录 1、特征工程的重要性 2、缺失值和异常值的处理 &#xff08;1&#xff09;处理缺失值 &#xff08;2&#xff09;处理异常值 3、回归模型的诊断 &#xff08;1&#xff09;残差分析 &#xff08;2&#xff09;检查回归假设 &#xff08;3&#xff09;Cooks 距离 4、学…

如何准确查询自己的大数据信用报告?

在当今数字化时代&#xff0c;大数据信用报告在个人信用评估中扮演着越来越重要的角色。然而&#xff0c;很多人可能不知道如何查询自己的大数据信用报告。本文贷大家一起了解一下&#xff0c;希望对你有帮助。 如何准确查询自己的大数据信用报告&#xff1a; 一、找到可靠的查…

学习Redis基础篇

1.初识Redis 1.认识NoSQL 2.认识Redis 3.连接redis命令 4.数据结构的介绍 5.通用命令 2.数据类型 1.String类型 常见命令&#xff1a;例子&#xff1a;set key value

(提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战

文章目录 &#xff08;提供数据集下载&#xff09;基于大语言模型LangChain与ChatGLM3-6B本地知识库调优&#xff1a;数据集优化、参数调整、提示词Prompt优化本地知识库目标操作步骤问答测试的预设问题原始数据情况数据集优化&#xff1a;预处理&#xff0c;先后准备了三份数据…

【AI数字人-论文】RAD-NeRF论文

文章目录 前言模型框架动态的NeRF前处理头部模型音频特征眼部控制头部总体表示 躯干模型loss 结果参考 【AI数字人-论文】AD-NeRF论文 前言 本篇论文有三个主要贡献点&#xff1a; 提出一种分解的音频空间编码模块&#xff0c;该模块使用两个低维特征网格有效地建模固有高维音…

ChatGPT调教指南 | 咒语指南 | Prompts提示词教程(一)

在我们开始探索人工智能的世界时&#xff0c;了解如何与之有效沉浸交流是至关重要的。想象一下&#xff0c;你手中有一把钥匙&#xff0c;可以解锁与OpenAI的GPT模型沟通的无限可能。这把钥匙就是——正确的提示词&#xff08;prompts&#xff09;。无论你是AI领域的新手&#…

Linux线程同步(3)生产者与消费者、条件变量与信号量

1.生产者与消费者的概念 生产者与消费者&#xff08;Producer-Consumer&#xff09;问题&#xff0c;是一个经典的并发编程问题。在这个问题中&#xff0c;涉及到两类进程&#xff1a;生产者和消费者。生产者负责生产数据&#xff0c;并将其放入一个缓冲区中&#xff1b;消费者…

C# (WebApi)整合 Swagger

SpringBoot-整合Swagger_jboot整合swagger-CSDN博客 C# webapi 也可以整合Swagger webapi运行其实有个自带的HELP页面 但是如果觉得UI不好看&#xff0c;且没办法显示方法注释等不方便的操作&#xff0c;我们也可以整合Swagger 一、使用NuGet控制台安装Swagger 在菜单中选择…

网络安全笔记总结

IAE引擎 1.深度检测技术--DFI和DPI技术 DFI和DPI都是流量解析技术&#xff0c;对业务的应用、行为及具体信息进行识别&#xff0c;主要应用于流量分析及流量检测。 DPI&#xff1a;深度包检测技术 DPI是一种基于应用层的流量检测和控制技术&#xff0c;对流量进行拆包&#x…

【Spring】 AOP面向切面编程

文章目录 AOP是什么&#xff1f;一、AOP术语名词介绍二、Spring AOP框架介绍和关系梳理三、Spring AOP基于注解方式实现和细节3.1 Spring AOP底层技术组成3.2 初步实现3.3 获取通知细节信息3.4 切点表达式语法3.5 重用&#xff08;提取&#xff09;切点表达式3.6 环绕通知3.7 切…

Matplotlib绘制炫酷散点图:从二维到三维,再到散点图矩阵的完整指南与实战【第58篇—python:Matplotlib绘制炫酷散点图】

文章目录 Matplotlib绘制炫酷散点图&#xff1a;二维、三维和散点图矩阵的参数说明与实战引言二维散点图三维散点图散点图矩阵二维散点图进阶&#xff1a;辅助线、注释和子图三维散点图进阶&#xff1a;动画效果和交互性散点图矩阵进阶&#xff1a;调整样式和添加密度图总结与展…

鸿蒙开发(五)鸿蒙UI开发概览

从用户角度来讲&#xff0c;一个软件拥有好看的UI&#xff0c;那是锦上添花的事情。再精确的算法&#xff0c;再厉害的策略&#xff0c;最终都得通过UI展现给用户并且跟用户交互。那么&#xff0c;本篇一起学习下鸿蒙开发UI基础知识&#xff0c;认识下各种基本控件以及使用方式…

python 3.7.3的安装

参考 Linux安装Python3.7-良许Linux教程网 (lxlinux.net) 1、Index of /ftp/python/3.7.9/ 1、安装gcc&#xff0c;yum -y install gcc 2、 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel…

Llama2模型的优化版本:Llama-2-Onnx

Llama2模型的优化版本&#xff1a;Llama-2-Onnx。 Llama-2-Onnx是Llama2模型的优化版本。Llama2模型由一堆解码器层组成。每个解码器层&#xff08;或变换器块&#xff09;由一个自注意层和一个前馈多层感知器构成。与经典的变换器相比&#xff0c;Llama模型在前馈层中使用了不…

vue3 toRefs之后的变量修改方法

上效果 修改值需要带上解构之前的对象名obj&#xff0c; changeName:()>{ // toRefs 解决后变量修改值方法&#xff1a; 解构前变量.字段新值 obj.name FEIFEI; } } 案例源码 <!DOCTYPE html> <html> <head><me…

普中51单片机学习(十一)

独立按键 独立按键原理 按键在闭合和断开时触电存在抖动现象 硬件消抖电路如下 实验代码 #include "reg52.h" typedef unsigned char u8; typedef unsigned int u16;void delay(u16 i) {while(i--); } sbit ledP2^0; sbit k1P3^1;void keypro() {if(k10){delay(1…

yolov9目标检测报错AttributeError: ‘list‘ object has no attribute ‘device‘

最近微智启软件工作室在运行yolov9目标检测的detect.py测试代码时&#xff0c;报错&#xff1a; File “G:\down\yolov9-main\yolov9-main\detect.py”, line 102, in run pred non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_detmax_det) Fil…

css实现悬浮卡片

结果展示 html代码 <!doctype html> <html lang"zh"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <meta name"viewport" content"…
推荐文章