系统编程-信号

6 信号与管道 1

目录

6 信号与管道 1

信号

信号的概念

信号的使用

信号的发送

通过函数来实现信号的发送

信号改造函数(重点)

给自己发送信号函数

定时闹钟函数

暂停进程的函数

例题:

代码一:

代码二:

代码分析


-- linux系统下的进程间通信

  • 一共六种
  • 信号 管道 消息队列 共享内存 信号量集 套节字

信号

信号的概念

-- 信号是进程在运行过程中,由自身产生或由进程外部发过来的消息(事件)。
-- 信号是硬件中断的软件模拟(软中断) 。

-- 每一个信号用一个整型常量宏表示,以 SIG 开头,比如 SIGCHLD、SIGINT 等, 它们在系统头文件<signal.h> 中定义, 也可以通过在终端键入kill -l查看信号列表,或者键入 man 7

alt text

-- 1~31号信号是从unix上面继承过来的 不可靠信号 没有排队机制
-- 34~64是后面补充的信号 可靠信号
-- 信号大部分都是让进程死亡的

信号的使用

-- 主要去搞清楚 一些信号是如何产生的以及如何使用

  • SIGHUP:从终端上发出的结束信号; 1
  • SIGINT:来自键盘的中断信号(Ctrl-C); 2
  • SIGQUIT:来自键盘的退出信号(Ctrl-\); 3
  • SIGFPE: 浮点异常信号(例如浮点运算溢出);
  • SIGKILL:该信号结束接收信号的进程; 9
  • SIGALRM:进程的定时器到期时,发送该信号; 14
  • SIGTERM: kill 命令发出的信号;
  • SIGCHLD:标识子进程停止或结束的信号; 17
    -- 子进程给父进程主动发送的信号(有以下三种情况父进程会向子进程发送信号)
    -- 1、子进程死亡
    -- 2、子进程由运行转为暂停
    -- 3、子进程由暂停转为继续运行
  • SIGSTOP:来自键盘(Ctrl-Z)或调试程序的停止执行信号 19
  • SIGCONT: 18信号 继续运行信号

信号的发送

-- 在终端上发送信号

  • kill -num pid
  • 发送第num个信号到pid这个进程上去

例如:

alt text

alt text

通过函数来实现信号的发送

-- 函数头文件

  • #include <sys/types.h>
  • #include <signal.h>

-- 函数原型

  • int kill(pid_t pid, int sig);

-- 函数的作用:

  • 给指定的进程发送一个信号

-- 函数的参数:

  • pid:要给哪一个进程发送信号
  • sig:发送的信号

-- 函数的返回值:

  • 成功 0
  • 失败 -1

alt text

信号改造函数(重点)

-- 可以让信号原本的效果消失, 转而去执行相应的函数

-- 函数头文件

  • #include <signal.h>

-- 函数原型

  • sighandler_t = void (*) (int)
  • typedef void (*sighandler_t)(int);
  • sighandler_t signal(int signum, sighandler_t handler);

-- 函数的作用:

  • 将第一个参数中所填写的信号进行改造
  • 让他原本的效果消失
  • 接收到这个信号我们的进程会去运行 第二个参数所填写函数

-- 函数的参数:

  • signum:填写要进行改造的信号
  • 9信号、18 继续、 19 暂停不可以被改造和忽略
  • handler:函数指针指向void (*)(int )类型的函数
  • 当signal函数运行完之后
  • 再次接收到signum信号 会调用handler所指向的函数
  • handler如果参数选SIG_DFL,信号的改变就会恢复默认操作
  • SIG_IGN 对该信号进行忽略

-- 函数的返回值:

  • 成功返回 第二个参数的地址
  • 失败返回 SIG_ERR

alt text

alt text

给自己发送信号函数

--- 函数头文件

  • #include <signal.h>

-- 函数原型

  • int raise(int sig)

-- 函数的作用:

  • 给当前掉用该函数的进程发送一个信号

-- 函数的参数:

  • sig:要给自己发送的信号

-- 函数的返回值:

  • 成功 0
  • 失败 非 0

alt text

定时闹钟函数

-- 函数头文件

  • #include <unistd.h>

-- 函数原型

  • unsigned int alarm(unsigned int seconds);

-- 函数的作用

  • 定一个闹钟 计时结束之后会给当前进程发送一个闹钟信号

-- 函数的参数:

  • seconds:要计时的秒数
  • 给0表示取消之前定的闹钟

-- 函数的返回值:

  • 如果前面定过闹钟返回 上一个闹钟的剩余秒数
  • 如果前面没有定义过闹钟,返回 0

alt text

暂停进程的函数

-- 函数头文件

  • #include <unistd.h>

-- 函数原型

  • int pause(void); -- 函数的作用:
  • 当程序运行到 pause 函数的时候 会暂停
  • 当捕获到一个信号的时候 会解除暂停

-- 函数的返回值

  • 解除暂停返回 -1

alt text

例题:

-- 实现无界面的 MP3 播放器

-- 能实现 上下切歌、播放、暂停、自动播放功能

-- 需要依靠改造 17 信号来实现

-- 17 信号的发出条件 (子进程的状态发生了改变)

  • 1 子进程死亡 会 发出 17 信号给父进程
  • 2 由运行转为暂停的时候也会发送 17 信号
  • 3 由暂停转为继续的时候也会发送 17 信号

alt text

alt text

代码一:

#include "stdio.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include "string.h"
#include "unistd.h"
#include <stdlib.h>
#include "signal.h"char * name[20] ={0};
int count = 0;
int i = 0;
pid_t pid;
//子进程被暂停和继续也会发送17信号
//子进程死亡的时候发送的17信号
//需要判断子进程是否存活
void func(int a)
{printf("接收到17信号\n");//wait(NULL);会阻塞pid_t p = waitpid(pid,NULL,WNOHANG);if(p == 0)//子进程没有死亡return ;i++;//偏移下标if(i == count)//判断是否超了i = 0;else if(i < 0)i = count -1;pid = vfork();if(pid == 0){execlp("mpg123","mpg123",name[i],NULL);}
}int main(int argc,char*argv[])
{//1 获取歌曲的绝对路径  目录操作DIR * dir = opendir(argv[1]);if(dir == NULL){perror("opendir()");return -1;}//2 循环读取获取目录下的所有文件while(1){struct dirent * file = readdir(dir);if(file == NULL)break;//循环的结束条件//查找所有文件后缀为.mp3的文件if(strstr(file->d_name,".mp3")){//1 把歌的绝对路径存起来name[count] = malloc(200);sprintf(name[count],"%s/%s",argv[1],file->d_name);count++;}}for(int i =0;i<count;i++)printf("%s\n",name[i]);while(1)//失效{pid = vfork();if(pid == 0){execlp("mpg123","mpg123",name[i],NULL);}else if(pid>0){//从键盘输入要进行的操作char a = 0;signal(17,func);//信号改造函数//当接收到17信号 会自动的调用func函数//子进程给父进程发送17信号 父进程就会调用func函数while(1){scanf("%c",&a);//阻塞 等待键盘输入getchar();//根据不同的值进行不同的操作switch(a){   //暂停case 'p': kill(pid,19);//发送暂停信号printf("暂停\n");break;case 'c':kill(pid,18);//发送继续信号printf("继续\n");break;case 'b':kill(pid,9);i=i-2;printf("上一曲\n");break;case 'n': //突然发现只要子进程死亡 会自动调用func函数//去播放下一个音乐kill(pid,9);//给指定的进程发送信号printf("下一曲\n");break;}}}}return 0;   
}

alt text

代码二:

#include "stdio.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include "string.h"
#include "unistd.h"
#include <stdlib.h>#include <signal.h>char * name[20] ={0};
int count = 0;
int a=0;
pid_t pid = -1;      // 当前播放的子进程IDint i=0;
pid_t d =0;void handleInput() ;
void playSong(int i) ;
void func(int a) ;int main(int argc,char*argv[])
{if(argc==1){printf("请填写参数\n");return -1;}DIR * dir = opendir(argv[1]);if(dir == NULL){perror("opendir()");return -1;}while(1){struct dirent * file = readdir(dir);if(file == NULL)break;if(strstr(file->d_name,".mp3")){name[count] = malloc(300);sprintf(name[count],"%s/%s",argv[1],file->d_name);count++;}}closedir(dir);for(int i =0;i<count;i++)printf("%s\n",name[i]);signal(17,func);playSong(i);handleInput();for (int i = 0; i < count; i++) {  free(name[i]);  } return 0;   
}void playSong(int i) 
{  if (pid != -1) {  kill(pid, 9);   wait(NULL);  }  pid = fork();  if (pid == 0) {  execlp("mpg123", "mpg123", name[i], NULL);   exit(1);  } 
} void func(int a) {  if (a == 17) {  printf("子进程状态发生改变!\n");  d = waitpid(-1,&a,WNOHANG);if(d >0){i++;  if (i >= count) {  i = 0;   }  playSong(i); }}  
} void handleInput() {  char n;  while (1) {  printf("请输入命令(p: 暂停, s: 继续, n: 下一首, l: 上一首): \n");  scanf(" %c", &n);switch (n) {  case 'p':  if (pid != -1) { kill(pid, 19); // 暂停子进程  }  break;  case 's':  if (pid != -1) {  kill(pid, 18); // 继续子进程  }  break;  case 'n':  if (pid != -1) {  kill(pid, 9); // 终止当前进程  wait(NULL);  }  i++;  if (i >= count) {  i = 0; // 循环到第一首歌  }  playSong(i);  break;  case 'l':  if (pid != -1) {  kill(pid, 9); // 终止当前进程  wait(NULL);  }  i--;  if (i < 0) {  i = count - 1; // 循环到最后一首歌  }  playSong(i);  break;  default:  printf("无效命令\n");  break;  }  }  
}  
代码分析

alt text

alt text

alt text

alt text

alt text

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

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

相关文章

获发明专利加持,隆道加速推进企业级AI应用落地

近期&#xff0c;北京隆道网络科技有限公司研发的“基于供应链管理的AI采购业务分析装置及方法”获得国家发明专利授权。该项新专利的取得&#xff0c;证明了隆道在AI产业化应用中的技术前瞻性和创新性&#xff0c;也为隆道加速企业级AI应用落地提供了知识产权保障。 根据IBM发…

将标准输入stdin转换成命令行参数——Unix中的xargs指令

xargs是Unix中的复合指令加工机&#xff0c;联合管道符“|”将制造更加强大的“复杂”指令组合。 (笔记模板由python脚本于2024年08月22日 18:13:51创建&#xff0c;本篇笔记适合喜欢Linux的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.…

开放式耳机哪个品牌好?分享四款开放式蓝牙耳机排行榜前十名

我相信很多人都会有这些问题&#xff0c;不知道入手什么蓝牙耳机品牌、有线耳机不好收纳、有线耳机不方便携带、蓝牙耳机听歌的音质怎么样、蓝牙耳机是否会对大脑有危害、蓝牙耳机有什么品牌型号推荐以及想要不同价位的蓝牙耳机品牌推荐参考&#xff0c;okok问题也是很多&#…

GPU池化技术在油气勘探开发中的应用

01 背景介绍 国内某研究院为实现石油勘探开发专业软件资源的统一管理、统一监控、统一共享和统一计量&#xff0c;自主研发了勘探云管理平台(EPCP)和科研工作业务协同平台。该研究院通过两个平台实现了数十种专业勘探开发软件的共享&#xff0c;种类包括地震资料处理和解释&am…

汽车冷却液温度传感器

1、冷却液温度传感器的功能 发动机冷却液温度传感器&#xff0c;也称为ECT&#xff0c;是帮助保护发动机&#xff0c;提高发动机工作效率以及帮助发动机稳定运行的非常重要的传感器之一。 发动机冷却液温度 &#xff08;ECT&#xff09; 传感器用于测量发动机的冷却液温度&…

【Lecture1】清华大学大模型公开课——大模型绪论

#清华大模型公开课第二季 #OpenBMB 目录 1. The Evolution of Artificial Intelligence --History 人工智能的演变--历史 1.1 Definition of AI --定义 1.2 Conceptualization of AI -- 概念 1.3 Birth of AI as a Discipline 1.4 Development of AI 1.4.1 Symbolic Int…

有哪些好用的AI工具?这些AI工具让工作学习更高效!

大家好&#xff01;今天我要给大家介绍一些非常酷的AI工具&#xff0c;它们可以帮助你在不同领域发挥创意和提高效率。让我们一起来探索吧&#xff01; 我们有AI绘画工具。想象一下&#xff0c;你只需要描述一下你想要的画面&#xff0c;AI就能帮你生成各种风格的艺术作品。无论…

Prometheus 服务发现

目录 1.基于文件的服务发现 2.基于 Consul 的服务发现 3.基于 Kubernetes API 的服务发现 1.基于文件的服务发现 基于文件的服务发现是仅仅略优于静态配置的服务发现方式&#xff0c;它不依赖于任何平台或第三方服务&#xff0c;因而也是最为简单和通用的实现方式。 Prometh…

8月21日笔记

Frp Frp(Fast e Reverse ) Proxy) 是一款简单&#xff0c;好用&#xff0c;稳定的隧道工具。Frp 使用 Go语言开发&#xff0c;支持跨平台&#xff0c;仅需下载对应平台的二进制文件即可执行&#xff0c;没有额外依赖。它是一款高性能的反向代理应用&#xff0c;可以轻松地进行…

解决k8s分布式集群,子节点加入到主节点失败的问题

1.问题情况 Master主节点在 使用 kubeadm init 成功进行初始化后&#xff0c;如下所示 Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/k…

CMakeLists.txt模板

#设置编译该CMakeLists.txt文件所需要的最低cmake版本 CMAKE_MINIMUM_REQUIRED(VERSION 最低版本号)# 该项目名称 PROJECT(项目名称)SET(CMAKE_CXX_STANDARD 11)SET(CMAKE_C_STANDARD 11)# 此行可以理解为将路径下所有的文件装载到自定义集合filelist中 FILE(GLOB filelist &q…

黑神话·悟空修改器免费下载

《黑神话&#xff1a;悟空》是一款备受期待的动作角色扮演游戏&#xff0c;由中国独立游戏开发团队Game Science&#xff08;游戏科学&#xff09;开发。 一、修改器下载地址 通过百度网盘分享的文件&#xff1a;黑神话悟空修改器.zip 链接&#xff1a;https://pan.baidu.com/s…

IO进程(7)

目录 1.信号 1.1信号函数 1.1.1信号处理函数 信号的处理过程 2.共享内存 2.1概念 2.2特点 ​​​​​​​​​​​​​​2.3步骤 ​​​​​​​2.4函数接口创建 2.4.1key值 ​​​​​​​​​​​​​​2.4.2创建或打开共享内存 ​​​​​​​​​​​​​​2.4.3映射共享内…

pat1074 k个一组反转链表

是我的错觉吗 直接把%d赋值给数组小标&#xff0c;不能把值副进去&#xff1f; 可是这样可以&#xff1f; 乱套了这 同样的代码 所以暂时将你眼睛闭了起来 所以还是好好老实两次赋值 。。。 写糊了已经 注意这句话 链表中部翻转&#xff1a; 不带dummy真的好麻烦且头…

用Python解决预测问题_多元线性回归模板

多元线性回归是一种统计学方法&#xff0c;用于分析两个或多个自变量&#xff08;解释变量&#xff09;与一个因变量&#xff08;响应变量&#xff09;之间的关系。在最简单的线性回归模型中&#xff0c;只有一个自变量和一个因变量&#xff0c;它们之间的关系可以用一条直线来…

绿色能源的应用与节约,低碳生活方式指南

在这个全球化的时代&#xff0c;环境问题越来越严重&#xff0c;大家都关注的绿色能源和节约成了热门话题。怎样在日常生活中用好绿色能源&#xff0c;实现低碳生活&#xff0c;是每个环保人士都需要了解的关键问题。这篇文章会详细告诉你绿色能源的使用、优点、节约方法以及低…

msxml*.dll 错误 ‘80072f7d‘ 安全频道支持出错 解决方案

诡异的 msxml6.dll错误 80072f7d安全频道支持出错&#xff0c;用 SSLTools.exe 修复的方法无效&#xff01;&#xff01;&#xff01; ’--------------------------------------------------------------- 有如下简要 ASP 代码&#xff0c;用于获取网页链接返回内容&#xf…

window系统开代理在Conda环境中导致pip安装python包出现timeout

文章目录 1: 临时性配置 pip 代理文件2. 永久性配置 pip 代理文件 在使用 Conda 时&#xff0c;如果你设置了代理&#xff0c;但 pip 仍然无法工作&#xff0c;可能需要确保代理配置正确并适用于 pip。以下是几种可能的解决方法&#xff0c;先看一下报错 WARNING: Retrying (Re…

物联网设备字符串转串口指令-SAAS本地化及未来之窗行业应用跨平台架构

一、指令转换作用 现在服务器一般采用json数据格式 但是终端底层都是二进制指令 直接从服务器传输的指令就无法执行&#xff0c;因此需要转换 二、转换源码 void StringToHandleCommand(byte *byteArray, const char *hexString) {bool oddLength strlen(hexString) &…

【威锋网-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…