进程间通信——进程与线程——day12

在进程间的通信,主要分为6部分内容,分别是:管道、信号、消息队列、共享内存、信号灯以及套接字

今天主要讲一下管道以及信号

管道

无名管道: 无名管道只能用于具有亲缘关系的进程间通信

pipeint pipe(int pipefd[2]);功能:创建一个无名管道参数:pipefd[0]:读管道文件描述符pipefd[1]:写管道文件描述符返回值:成功返回0 失败返回-1
无名管道特性:
1.管道中至少有一个写端: 读取数据时,如果管道中有数据直接读取,管道中没有数据阻塞等待直到有数据写入读出,继续向后执行
2.管道中没有写端:读取数据时,如果管道中有数据直接读取,管道中没有数据不阻塞等待直接向下执行
3.管道中至少有一个读端:写入数据时,如果管道中没有存满(64k),则直接写入,管道中如果存满,则阻塞等待直到有数据读出,才能继续写入
4.管道中没有读端:写入数据时,会产生管道破裂错误,导致程序崩溃

例子:在父进程中创建子进程, 在子进程中写hello world,通过管道,让其在父进程中打印出来。

#include"head.h"int main(void)
{pid_t pid;	//子进程IDint fd[2];	int ret = 0;char tmpbuff[4096] = {0};ret = pipe(fd);		//创建管道if(-1 == ret){perror("fail to pipe");return -1;}pid = fork();	//创建子进程if(-1 == pid){perror("fail to fork");return -1;}if(0 == pid)	//pid=0为子进程{strcpy(tmpbuff,"hello world!");write(fd[1],tmpbuff,sizeof(tmpbuff));	//写入}else if(pid > 0)	//进入父进程{sleep(3);read(fd[0],tmpbuff,sizeof(tmpbuff));	printf("%s\n",tmpbuff);		//输出}while(1){}close(fd[0]);close(fd[1]);	return 0;
}

结果:
在这里插入图片描述

有名管道:打开管道文件 -> 读写管道文件 -> 关闭管道文件

注意:有名管道必须读写两端同时加入才能继续向下执行

mkfifo int mkfifo(const char *pathname, mode_t mode);功能:创建一个管道文件参数:pathname:管道文件路径mode:权限返回值:成功返回0 失败返回-1

例子:编写两个进程,A B,两个进程都可以互发消息

首先我们先写进程A,因为两个进程的内容都相等,改的地方不大,在这边只展示A即可
#include "head.h"int fatob = 0;
int fbtoa = 0;
pthread_t tid_send;	//线程
pthread_t tid_recv;void *sendfun(void *arg)	//发送
{	char tmpbuff[1024] = {0};while (1){memset(tmpbuff, 0, sizeof(tmpbuff));	//用于初始化数组gets(tmpbuff);	write(fatob, tmpbuff, strlen(tmpbuff));	//在atob管道中,传入数据if (!strcmp(tmpbuff, ".quit")){break;}}pthread_cancel(tid_recv);		//若该线程结束,则recvfun线程也结束return NULL;
}void *recvfun(void *arg)
{char tmpbuff[1024] = {0};while (1){memset(tmpbuff, 0, sizeof(tmpbuff));read(fbtoa, tmpbuff, sizeof(tmpbuff));	//在btoa管道中,读取数据if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:%s\n", tmpbuff);	//输出}pthread_cancel(tid_send);return NULL;
}int main(void)
{char tmpbuff[1024] = {0};mkfifo("/tmp/ATOB", 0777);	//创建管道,并定义权限为0777mkfifo("/tmp/BTOA", 0777);fatob = open("/tmp/ATOB", O_WRONLY);	//以只写的方式打开ATOB管道if (-1 == fatob){perror("fail to open");return -1;}fbtoa = open("/tmp/BTOA", O_RDONLY);	//以只读的方式打开BTOA管道if (-1 == fbtoa){perror("fail to open");return -1;}pthread_create(&tid_send, NULL, sendfun, NULL);	//创建线程pthread_create(&tid_recv, NULL, recvfun, NULL);pthread_join(tid_send, NULL);	//回收线程空间,具有阻塞作用pthread_join(tid_recv, NULL);close(fatob);	//关闭管道close(fbtoa);return 0;
}

结果:
在这里插入图片描述
此时,两进程可以相互通信了。

信号:信号用来实现内核层和用户层信息的交互,也可以用来实现进程间通信

信号的种类:

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

以上就是所以的信号种类

信号处理方式

    1.缺省:按照系统默认的方式处理2.忽略:不响应信号3.捕捉:按照自定义方式处理信号9号信号SIGKILL19号信号SIGSTOP 这两个信号不能被忽略和捕捉以下三个信号可以从键盘输入:SIGINT:ctrl + c SIGQUIT:ctrl + \SIGTSTP:ctrl + z

signal

typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);
功能:改变信号的处理方式
参数:signum:信号的编号handler:信号的处理方式SIG_IGN     忽略处理SIG_DFL     缺省处理函数首地址   捕捉处理
返回值:成功返回之前处理函数的首地址失败返回SIG_ERR

eg:编写一个进程循环执行while (1)
当按下 SIGINT(ctrl + c) 打印SIGINT信号来了
当按下 SIGQUIT(ctrl + ) 打印SIGQUIT信号来了
当按下 SIGTSTP(ctrl + z) 打印SIGTSTP信号来了

#include"head.h"void hander1(int signo)
{printf("SIGINT is comming!\n");return;
}void hander2(int signo)
{printf("SIGQUIT is comming!\n");return;
}void hander3(int signo)
{printf("SIGQUIT is comming!\n");return;
}int main(void)
{signal(SIGINT,hander1);		//参数1:信号编号signal(SIGTSTP,hander3);	//参数2:处理方式,我们这里采用捕捉处理signal(SIGQUIT,hander2);while(1){}return 0;
}

结果:
在这里插入图片描述
以上就是今天的内容,谢谢大家!

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

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

相关文章

水豚鼠标助手 强大的鼠标美化工具

水豚鼠标助手 水豚鼠标助手是一款 鼠标换肤、屏幕画笔、放大镜、聚光灯、屏幕放大、倒计时功能的强大屏幕演示工具。 软件助手获取 水豚鼠标助手1.0.0 安装教程 第一步:下载后,双击软件安装包 第二步:Windows可能会出现提示弹窗&#xff…

分享:大数据信用报告查询的价格一般要多少钱?

现在很多人都开始了解自己的大数据信用了,纷纷去查大数据信用报告,由于大数据信用与人行征信有本质的区别,查询方式和价格都不是固定的,本文就为大家详细讲讲大数据信用报告查询的价格一般要多少钱,希望对你有帮助。 大…

网站SSL证书有什么用?

网站SSL证书的作用至关重要,它主要体现在以下几个方面: 1. 数据加密: - SSL证书通过HTTPS协议为网站提供数据加密功能,确保用户与服务器之间传输的信息经过加密处理,包括但不限于登录凭证、交易信息、个人信息等敏…

【web APIs】6、(学习笔记)有案例!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、正则表达式正则基本使用元字符边界符量词范围字符类 二、替换和修饰符三、正则插件change 事件判断是否有类 四、案例举例学生就业信息表用户注册界面用户登…

Docker技术概论(5):Docker网络

Docker技术概论(5) Docker网络 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog…

阿里云服务器大降价20%,简单拥有五年三台2h4gECS,组建公网集群

要在阿里云ECS上组建集群,您可以按照以下步骤进行操作: 创建ECS实例:登录阿里云控制台,选择ECS实例,点击“创建实例”按钮。根据实际需求选择实例的配置参数,例如实例规格、操作系统、网络等。根据需要选择…

如何在Linux使用Docker部署Nexus容器并实现公网访问本地仓库【内网穿透】

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具,用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关,可…

谷歌SEO推广提高网站点击率的10个秘籍-华媒舍

在当今数字化时代,拥有一个高点击率的网站对于企业和个人而言至关重要。通过谷歌SEO推广,可以帮助网站吸引更多的流量,并在搜索引擎结果页面(SERP)中获得更好的排名。本文将介绍10个谷歌SEO推广的秘籍,帮助…

snakeyaml1.x升级2.x导致项目启动报错

snakeyaml1.x升级2.x,修复漏洞 1.背景 在工作中,经常会有漏洞扫描,有一次看到了snakeyaml的漏洞: 项目框架:springBoot 版本:2.2.6.RELEASE snakeyaml 中央仓库信息 snakeyaml中央仓库地址:https://m…

ETH开源PPO算法学习

前言 项目地址:https://github.com/leggedrobotics/rsl_rl 项目简介:快速简单的强化学习算法实现,设计为完全在 GPU 上运行。这段代码是 NVIDIA Isaac GYM 提供的 rl-pytorch 的进化版。 下载源码,查看目录,整个项目…

mongoose源码解读(二) -- mg_mgr_init 初始化

在用 mongoose 源码开发的时候,这个初始化函数 mg_mgr_init()则是必须的,我们看下它到底做了哪些初始化操作。 void mg_mgr_init(struct mg_mgr *m, void *user_data) {struct mg_mgr_init_opts opts;memset(&opts, 0, sizeo…

力扣-移除元素

问题 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长…