C/C++进程超详细详解【下部分】(系统性学习day8)

目录

前言

一,有名管道通信

1 .概念

2 .创建有名管道

实例代码如下:

二、信号通信

1 .概念

2 .用户进程对信号的响应方式

3. 用户进程对常用信号的缺省操作

4. 信号处理流程

5. 信号相关函数(系统调用)

 5.1 kill - 给指定进程发送信号

实例代码如下: 

5.2 raise() --给当前进程发送信号  

实例代码如下: 

5.3 alarm() 在进程中设置定时器(闹钟)  

实例代码如下: 

5.4 pause() 使进程挂起  

 实例代码如下:

5.5 signal 注册信号  

实例代码如下: 

总结


前言

上篇博客对C/C++进程的中部分进行了详细讲解,本篇博客将继续讲解和补充关于线程的知识点。


一,有名管道通信

1 .概念

1.由于无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围。

2.而有名管道可以使互不相关的两个进程互相通信。有名管道可以通过路径名来指出,并且在文件系统中可见

3.进程通过文件IO来操作有名管道

2 .创建有名管道

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
//参数1 ---- 管道的名称
//参数2 ---- 管道的权限
//返回值 -----成功:0,失败:-1

例如:

int main(int argc ,char **argv)
    {

        if(argc != 2){
            fprintf(stderr,"Usage: %s <fifoname>\n",argv[0]);
            exit(1);
        }

        //创建有名管道
        if(mkfifo(argv[1],0666) < 0){   //管道权限= 0666 & ~umusk
            perror("mkfifo");
            exit(1);
        }

        return 0;
    }

实例代码如下:

//从管道读10个整数,然后排序,并打印
int main(int argc ,char **argv)
{int fd;int a[10],i,j,flag;if(argc != 2){fprintf(stderr,"Usage: %s <fifoname>\n",argv[0]);exit(1);}//判断管道文件是否存在,如果不存在则创建,存在则直接打开if(access(argv[1],F_OK)){//创建有名管道if(mkfifo(argv[1],0666) < 0){   //管道权限= 0666 & ~umuskperror("mkfifo");exit(1);}}//打开管道if((fd = open(argv[1],O_RDWR)) < 0){perror("open");exit(1);}//从管道中读10个整数if(read(fd,a,sizeof(a)) < 0){perror("read");exit(1);}//排序for(i = 0; i < 9; i++){flag = 1;for(j = 0; j < 9-i; j++)if(a[j] > a[j+1]){a[j] = a[j] + a[j+1];a[j+1] = a[j] - a[j+1];a[j] = a[j] - a[j+1];flag = 0;}if(flag)break;}for(i = 0; i < 10; i++){printf("%d  ",a[i]);fflush(stdout);sleep(1);}printf("\n");close(fd);return 0;
}
//从键盘输入10个整数,并写入管道
int main(int argc ,char **argv)
{int fd;int a[10],i;if(argc != 2){fprintf(stderr,"Usage: %s <fifoname>\n",argv[0]);exit(1);}//判断管道文件是否存在,如果不存在则创建,存在则直接打开if(access(argv[1],F_OK)){//创建有名管道if(mkfifo(argv[1],0666) < 0){   //管道权限= 0666 & ~umuskperror("mkfifo");exit(1);}}//打开管道if((fd = open(argv[1],O_RDWR)) < 0){perror("open");exit(1);}//键盘输入10个整数printf("请输入10个整数:");for(i = 0; i < 10; i++){scanf("%d",&a[i]);}//向管道中写10个整数write(fd,a,sizeof(a));close(fd);return 0;
}

二、信号通信

1 .概念

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式

信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。

如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程

2 .用户进程对信号的响应方式

(1)忽略信号:
    对信号不做任何处理,但是有两个信号不能忽略:即SIGKILL及SIGSTOP。
(2)捕捉信号:
    定义信号处理函数,当信号发生时,执行相应的处理函数。
(3)执行缺省操作:
    Linux对每种信号都规定了默认操作

//查看linux系统中的信号---kill
peter@ubuntu:~/2308/proc/day03_code$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

3. 用户进程对常用信号的缺省操作

信号名含义默认操作
SIGHUP

该信号在用户终端连接(正常或非正常)结束时发出,通常是在终端的控   

制进程结束时,通知同一会话内的各个作业与控制终端不再关联。            

终止
SIGINT该信号在用户键入INTR字符(通常是Ctrl-C)时发出,终端驱动程序发送                  
此信号并送到前台进程中的每一个进程。                
终止
SIGQUIT该信号和SIGINT类似,但由QUIT字符(通常是Ctrl-\)来控制。终止
SIGILL该信号在一个进程企图执行一条非法指令时(可执行文件本身出现错误,                     
或者试图执行数据段、堆栈溢出时)发出。    
终止
SIGFPE

该信号在发生致命的算术运算错误时发出。这里不仅包括浮点运算错误,                   

 还包括溢出及除数为0等其它所有的算术的错误。    

终止
SIGKILL该信号用来立即结束程序的运行,并且不能被阻塞、处理和忽略。终止
SIGALRM该信号当一个定时器到时的时候发出。终止
SIGSTOP该信号用于暂停一个进程,且不能被阻塞、处理或忽略。暂停进程
SIGTSTP该信号用于暂停交互进程,用户可键入SUSP字符(通常是Ctrl-Z)发出这个信号。暂停进程
SIGCHLD子进程改变状态时,父进程会收到这个信号忽略
SIGABORT该信号用于结束进程终止

4. 信号处理流程

 

5. 信号相关函数(系统调用)

 5.1 kill - 给指定进程发送信号

#include <sys/types.h>
    #include <signal.h>
    int kill(pid_t pid, int sig);
    //参数1  -----信号发送的目标进程的ID
                 参数1取值分四种
                 pid > 0 ,给进程号为pid的进程发送信号
                 pid = 0 , 给当前进程组中每一个进程发送信号
                 pid = -1, 发送给进程表中所有的进程
                 pid < -1, 给指定进程组中的每一个进程发送信号,该进程组的ID为-pid
    //参数2  -----要发送的信号
    //返回值----成功:0,失败:-1

实例代码如下: 
int main(int argc,char **argv)
{
#if 1pid_t pid;if(argc != 2){fprintf(stderr,"Usage: %s <pid>\n",argv[0]);exit(1);}pid = atoi(argv[1]);   //atoi将字符串转为整数if(kill(pid,SIGKILL) < 0){perror("kill");exit(1);}
#elsepid_t pid1,pid2;int i;if((pid1 = fork()) < 0){perror("fork");exit(1);}else if(!pid1){   //子进程1for(i = 0; ; i++){printf("pid = %d\n",getpid());sleep(1);}}else{if((pid2 = fork()) < 0){perror("fork");exit(1);}else if(!pid2){  //子进程2for(i = 0; ; i++){printf("pid = %d\n",getpid());sleep(1);}}else{  //父进程for(i = 0; ; i++){printf("pid = %d\n",getpid());sleep(1);if(i == 5)//kill(0,SIGKILL); //0--给进程组中每一个进程发送信号kill(pid2,SIGKILL);  //给pid2发送信号}}}#endifreturn 0;
}

5.2 raise() --给当前进程发送信号  

#include <signal.h>
int raise(int sig);
//参数 ----信号
//返回值----成功:0,失败:-1

实例代码如下: 
int main(void)
{int i;for(i = 0; ; i++){printf("pid = %d\n",getpid());sleep(1);if(i == 7)raise(SIGKILL);}return 0;
}

5.3 alarm() 在进程中设置定时器(闹钟)  

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
//参数 ---- 要定时的秒数
//返回值 ----如果第一次调用该函数,返回值为0,
            如果调用之前已经设置了定时器,则返回上次定时剩余的秒数

实例代码如下: 
int main(void)
{int i,ret;ret = alarm(20);  // 从该语句开始计时,7秒之后发送SIGALRM信号给当前进程printf("ret = %d\n",ret);for(i = 0; ; i++){printf("pid = %d,i = %d\n",getpid(),i);sleep(1);if(i == 7){ret = alarm(5);printf("ret = %d\n",ret);}}return 0;
}

5.4 pause() 使进程挂起  

int pause(void);
//使进程挂起 ,直到进程收到任意一个信号则返回。

 实例代码如下:
//信号处理函数
void fun(int signo)
{int i;for(i = 0; i < 3; i++){printf(GREEN "正在吃饭\n"NONE);sleep(1);}
}int main(void)
{int i,j;//注册信号SIGALRMsignal(SIGINT,fun);for(i = 0; ; i++){pause();  //使进程挂起,直到收到信号为止for(j = 0; j < 5; j++){printf("正在睡觉\n");sleep(1);}}return 0;
}

5.5 signal 注册信号  

#include <signal.h>
typedef void (*sighandler_t)(int);  //定义函数指针类型名称
sighandler_t signal(int signum, sighandler_t handler);
//参数1 ---- 要注册的信号
//参数2 ---- 信号的响应方式:
                SIG_IGN   ----- 忽略信号
                SIG_DFL   ----- 对信号进行缺省操作
        信号处理函数的指针    ----- 捕捉信号,当收到信号,则会执行信号处理函数
        void xxx_fun(int)
        {
        
        }
//返回值 ----成功:信号处理函数指针,失败:SIG_ERR

实例代码如下: 
//信号处理函数
void eat(int signo)
{int i;for(i = 0; i < 3; i++){printf(GREEN "正在吃饭\n"NONE);sleep(1);}
}int main(void)
{int i;//注册信号SIGALRMsignal(SIGALRM,eat);for(i = 0; ; i++){if(i % 8 == 0){alarm(8);  // 从该语句开始计时,7秒之后发送SIGALRM信号给当前进程printf("开始睡觉,设置闹钟\n");}printf("正在睡觉......\n");sleep(1);}return 0;
}


总结

        本篇文章针对进程进行最后的超详细讲解和补充,希望能够帮到大家!

        以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!

       希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!

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

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

相关文章

gdb的使用

目录 gdb工具的使用 代码调试相关指令 运行程序指令 r 显示代码的指令 l 给代码打断点 b 查看断点位置 info b 执行代码到断点处停止 关闭断点 d断点编号 关闭某个断点&#xff0c;但不删除 disable编号 打开某个断点 enable断点编号 逐过程调试代码 n 逐语句调试代码 s 查看…

复习Day09:哈希表part02:141.环形链表、142. 环形链表II、454.四数相加II、383赎金信

之前的blog&#xff1a;https://blog.csdn.net/weixin_43303286/article/details/131765317 我用的方法是在leetcode再过一遍例题&#xff0c;明显会的就复制粘贴&#xff0c;之前没写出来就重写&#xff0c;然后从拓展题目中找题目来写。辅以Labuladong的文章看。然后刷题不用…

go-fastdfs分布式文件存储集群搭建和测试

一、官方文件 https://sjqzhang.github.io/go-fastdfs/#character2、集群原理 小集群原理&#xff1a; 大集群原理 二、服务端集群部署 1、在集群每个节点机器上下载安装包 (建议使用最新稳定版本&#xff09; wget --no-check-certificate https://github.com/sjqzhang/go…

CSS 创建

当读到一个样式表时&#xff0c;浏览器会根据它来格式化 HTML 文档。 如何插入样式表 插入样式表的方法有三种: 外部样式表(External style sheet)内部样式表(Internal style sheet)内联样式(Inline style) 外部样式表 当样式需要应用于很多页面时&#xff0c;外部样式表将是…

专题一:递归【递归、搜索、回溯】

什么是递归 函数自己调用自己的情况。 为什么要用递归 主问题->子问题 子问题->子问题 宏观看待递归 不要在意细节展开图&#xff0c;把函数当成一个黑盒&#xff0c;相信这个黑盒一定能完成任务。 如何写好递归 一、汉诺塔 class Solution { public:void dfs(vec…

react项目从webpack迁移到vite的解决方案

虽然webpack是前端工程编译工具的王者&#xff0c;但是最近vite牛逼吹的震天响&#xff0c;说什么开发/生产打包速度甩webpack 100条街。不管是不是事实&#xff0c;总得尝试一下吧。 于是说干就干&#xff0c;在网上找了很多资料&#xff0c;终于搞定了&#xff0c;以下就是r…

QT4.8.7安装详细教程

QT4.8.7安装详细教程&#xff08;MinGW 4.8.2和QTCreator4.2.0&#xff09; 1.下载及安装2.配置环境 此文是在下方链接博文的基础上&#xff0c;按自己的理解整理的https://blog.csdn.net/xiaowanzi199009/article/details/104119265 1.下载及安装 这三个文件&#xff0c;顺序是…

更直观地学习 Git 命令

theme: condensed-night-purple 前言 本文参考于 Learn Git Branching 这个有趣的 Git 学习网站。 在该网站&#xff0c;可以使用 show command 命令展示所有可用命令。 你也可以直接访问网站的sandbox&#xff0c;自由发挥。 本地篇 基础篇 git commit git commit将暂…

MySQL学习笔记23

逻辑备份&#xff1a; 1、回顾什么是逻辑备份&#xff1f; 逻辑备份就是把数据库、数据表或者数据进行导出&#xff0c;导出到一个文本文件中。 2、逻辑备份工具&#xff1a; mysqldump&#xff1a;提供全库级、数据库级别以及表级别的数据备份。 mysqldumpbinlog&#xff…

苹果签名有多少种类之TF签名(TestFlight签名)是什么?优势是什么?什么场合需要应用到?

&#xff08;一&#xff09;TestFlight 能够让您&#xff1a;邀请内部和外部的测试人员为应用程序提供反馈。 跟踪应用程序在测试过程中发现的 bug 和用户体验问题。 收集 Crash 报告&#xff0c;了解应用程序在真实设备上的运行状况。 要使用 TestFlight&#xff0c;您可以按照…

[Spring] Spring5——AOP 简介

目录 一、AOP 简介 1、什么是 AOP 二、AOP 底层原理 1、动态代理原理 2、基于接口的 JDK 动态代理 3、基于继承的 CGLib 动态代理 三、底层原理实现—— JDK 动态代理 1、使用 Proxy 类的方法创建代理对象 2、JDK 动态代理示例 四、AOP 操作术语 1、连接点 2、切入…

docker安装apisix全教程包含windows和linux

docker安装apisix 一、Windows安装1、首先需要安装docker和docker compose&#xff0c;如果直接安装docker desktop&#xff0c;会自动安装docker compose。2、重新启动电脑3、访问 Docker 的下载&#xff08;[https://www.docker.com/products/docker-desktop](https://www.do…

Java类型转换和类型提升

目录 一、类型转换 1.1 自动类型转换&#xff08;隐式&#xff09; 1.1.1 int 与 long 之间 1.1.2 float 与 double 之间 1.1.3 int 与 byte 之间 1.2 强制类型转换&#xff08;显示&#xff09; 1.2.1 int 与 long 之间 1.2.2 float 与 double 之间 1.2.3 int 与 d…

Docker01基础操作

目录 1、docker 发展历史 2、Docker 概述 2.1 容器 2.2 Docker与虚拟机的区别 2.3 容器在内核中支持2种重要技术 2.4 namespace的六项隔离 2.5 Docker核心概念 2.6 安装 Docker 2.7 Docker 镜像操作 2.8 Docker 容器操作 2.9 面试题 1、docker 发展历史 https://www.…

IO学习系列之使用多进程复制同一个文件内容

实例要求&#xff1a;使用多进程复制同一个文件内容&#xff1b;实例分析&#xff1a;1.创建一个父进程和一个子进程&#xff0c;设置光标在指定文件中的偏移量&#xff0c;实现对同一个文件的复制。2.比如&#xff1a;可以指定子进程复制文件内容的前一半&#xff0c;而父进程…

nvm 管理 node版本

下载地址 https://nvm.uihtm.com/download.html 基础命令 查看所有可安装的node版本 nvm list available 查看本地已经安装的所有版本&#xff1a; nvm list 安装指定的node版本 nvm install 14.18.1 使用指定node版本 nvm use 14.18.1 卸载指定node版本 nvm uninstall …

【网络编程】UDP数据报套接字编程和TCP流套接字编程

文章目录 1. 网络编程基础1.1 为什么需要网络编程&#xff1f;1.2 网络编程是什么&#xff1f;1.3 概念 2. Socket套接字3. UDP数据报套接字编程3.1 DatagramSocket API3.2 DatagramPacket API3.3 InetSocketAddress API 4. UDP构建服务端客户端&#xff08;一发一收&#xff0…

【Java-LangChain:使用 ChatGPT API 搭建系统-10】评估(下)-当不存在一个简单的正确答案时

第十章&#xff0c;评估&#xff08;下&#xff09;-当不存在一个简单的正确答案时 在上一章中&#xff0c;了解了如何评估 LLM 模型在 有明确正确答案 的情况下的输出&#xff0c;我们可以编写一个函数来判断 LLM 输出是否正确地分类并列出产品。 然而&#xff0c;如果 LLM …

文本分词排序

文本分词 在这个代码的基础上 把英语单词作为一类汉语&#xff0c;作为一类然后列出选项 1. 大小排序 2. 小大排序 3. 不排序打印保存代码 import jieba# 输入文本&#xff0c;让我陪你聊天吧~ lines [] print("请输入多行文本&#xff0c;以\"2333.3\"结束&am…

osg实现鼠标框选

目录 1. 需求的提出 2. 具体实现 2.1. 禁止场景跟随鼠标转动 2.2. 矩形框前置绘制 3. 附加说明 3.1. 颜色设置说明 3.2.矩形框显示和隐藏的另一种实现 1. 需求的提出 有时需要在屏幕通过按住键盘上的某个键如Ctrl键且按住鼠标左键&#xff0c;拖出一个矩形&#xff0c;实现框…