IO进程线程 day7 进程间通信

news2025/1/18 11:06:14

 1.使用消息队列完成两个进程之间相互通信

 2.信号通信相关代码的重新实现

(1)signal函数的实例

#include <head.h>

//定义信号处理函数
void handler(int signum)
{
    if(signum == SIGINT)      //表明要处理2号信号
    {
        printf("用户按下了ctrl + c键\n");
    }

    if(signum == SIGTSTP)          //处理暂停信号
    {

        printf("用户按下了ctrl + z键\n");
    }
}

/****************************主程序********************/
int main(int argc, const char *argv[])
{

    /*将SIGINT信号忽略
    if(signal(SIGINT, SIG_IGN) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }
    */

    /*将SIGINT信号默认处理
    if(signal(SIGINT, SIG_DFL) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }
    */

    //将SIGINT信号捕获
    if(signal(SIGINT, handler) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }

    //绑定SIGTSTP信号 ctrl + z
    if(signal(SIGTSTP, handler) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }



    while(1)
    {
        sleep(1);
        printf("我真的还想再活五百年\n");
    }

    return 0;
}

(2)尝试捕获SIGSTOP信号

#include <head.h>

//定义信号处理函数
void handler(int signum)
{
    if(signum == SIGINT)      //表明要处理2号信号
    {
        printf("用户按下了ctrl + c键\n");
    }

    if(signum == SIGTSTP)          //处理暂停信号
    {

        printf("用户按下了ctrl + z键\n");
    }


    if(signum == SIGSTOP)          //处理暂停信号
    {

        printf("用户按下了ctrl + z键\n");
    }
}

/****************************主程序********************/
int main(int argc, const char *argv[])
{
    /*尝试忽略SIGSTOP信号
    if(signal(SIGSTOP, SIG_IGN) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }
    */

    /*尝试捕获SIGSTOP信号
    if(signal(SIGSTOP, handler) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }
    */

    //尝试默认处理SIGSTOP信号
    if(signal(SIGSTOP, SIG_DFL) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }

    while(1)
    {
        sleep(1);
        printf("我真的还想再活五百年\n");
    }

    return 0;
}

(3)使用信号的方式以非阻塞的形式回收僵尸进程(SIGCHLD)

#include <head.h>

//定义信号处理函数
void handler(int signum)
{
    if(signum == 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++)
    {
        if(fork() == 0)
        {
            exit(EXIT_SUCCESS);
        }
    }


    while(1);


    return 0;
}

(4)使用闹钟信号完成一个定时器(SIGALRM),该信号由alarm函数设置的时间超时后产生

#include <head.h>

int main(int argc, const char *argv[])
{
    printf("%d\n", alarm(10));           //0

    sleep(5);


    printf("%d\n", alarm(10));           //5

    while(1);

    return 0;
}

(5)使用SIGALRM信号模拟斗地主出牌场景

#include <head.h>

//定义信号处理函数
void handler(int signo)
{
    if(signo == SIGALRM)
    {
        printf("系统已经随机为您出一张牌\n");
        alarm(5);
    }
}



int main(int argc, const char *argv[])
{
    
    char ch;

    //将SIGALRM信号绑定到信号处理函数中
    if(signal(SIGALRM, handler) == SIG_ERR)
    {
        perror("signal error");
        return -1;
    }

    while(1)
    {
        alarm(5);
        
        printf("请出牌:");
        scanf("%c", &ch);
        getchar();

        printf("您出的牌为:%c\n", ch);
    }

    return 0;
}

(6)信号发送函数(kill、raise)

#include <head.h>

//定义信号处理函数
void handler(int signo)
{
    if(signo == SIGUSR1)
    {
        printf("逆子何至于此\n");

        raise(SIGKILL);     //自杀
    }
}


int main(int argc, const char *argv[])
{
    
    //定义进程号
    pid_t pid = fork();

    if(pid > 0)
    {
        //父进程

        //将SIGUSR1信号绑定
        if(signal(SIGUSR1, handler) == SIG_ERR)
        {
            perror("signal error");
            return -1;
        }
        
        while(1)
        {
            printf("我真的还想再活五百年\n");
            sleep(1);
        }

    }else if(pid == 0)
    {
        //子进程
        printf("人生得意须尽欢,莫使金樽空对月\n");

        sleep(3);

        printf("我看透了红尘, 父亲跟我一起走吧\n");

        //向父进程发送一个信号
        kill(getppid(), SIGUSR1);

        exit(EXIT_SUCCESS);        //退出进程


    }else
    {
        perror("fork error");
        return -1;
    }


    return 0;
}

3.共享内存相关代码重新实现

(1)发送端

#include <head.h>
#define PAGE_SIZE 4096

int main(int argc, const char *argv[])
{
    //1、创建key值
    key_t key = -1;
    if((key = ftok("/", 't')) == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key = %#x\n", key);

    //2、将物理内存创建出共享内存段
    int shmid = 0;
    if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n", shmid);

    //3、将共享内存段地址映射到用户空间
    //NULL表示让系统自动选择页的分段
    //0表示当前进程对共享内存具有读写功能
    char *addr = (char *)shmat(shmid, NULL, 0);
    if(addr == (void *)-1)
    {
        perror("shmat error");
        return -1;
    }
    printf("addr = %p\n", addr);
    
    //4、操作共享内存
    //char buf[128] = "";
    while(1)
    {
        fgets(addr, PAGE_SIZE, stdin);   //从终端输入数据
        addr[strlen(addr) - 1] = '\0';    //将换行换成'\0'

        if(strcmp(addr, "quit") == 0)
        {
            break;
        }
    }

    
    //5、取消映射

    while(1);

    return 0;
}

(2)接收端

#include <head.h>
#define PAGE_SIZE 4096

int main(int argc, const char *argv[])
{
    //1、创建key值
    key_t key = -1;
    if((key = ftok("/", 't')) == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key = %#x\n", key);

    //2、将物理内存创建出共享内存段
    int shmid = 0;
    if((shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664)) == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n", shmid);

    //3、将共享内存段地址映射到用户空间
    //NULL表示让系统自动选择页的分段
    //0表示当前进程对共享内存具有读写功能
    char *addr = (char *)shmat(shmid, NULL, 0);
    if(addr == (void *)-1)
    {
        perror("shmat error");
        return -1;
    }
    printf("addr = %p\n", addr);
    
    //4、操作共享内存
    //char buf[128] = "";
    while(1)
    {
    
        printf("共享内存中的数据为:%s\n", addr);
        sleep(1);

        if(strcmp(addr, "quit") == 0)
        {
            break;
        }
    }

    
    //5、取消映射
    if(shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }


    //6、删除共享内存
    if(shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("shmctl error");
        return -1;
    }

    return 0;
}

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

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

相关文章

【数据结构】二叉树的链式实现

树是数据结构中非常重要的一种&#xff0c;在计算机的各方个面都有他的身影 此篇文章主要介绍二叉树的基本操作 目录 二叉树的定义&#xff1a;二叉树的创建&#xff1a;二叉树的遍历&#xff1a;前序遍历&#xff1a;中序遍历&#xff1a;后序遍历&#xff1a;层序遍历&#…

图解Kubernetes的服务(Service)

pod 准备&#xff1a; 不要直接使用和管理Pods&#xff1a; 当使用ReplicaSet水平扩展scale时&#xff0c;Pods可能被terminated当使用Deployment时&#xff0c;去更新Docker Image Version&#xff0c;旧Pods会被terminated&#xff0c;然后创建新Pods 0 啥是服务&#xf…

使用Excel批量给数据添加单引号和逗号

表格制作过程如下&#xff1a; A2表格暂时为空&#xff0c;模板建立完成以后&#xff0c;用来放置原始数据&#xff1b; 在B2表格内输入公式&#xff1a; ""&A2&""&"," 敲击回车&#xff1b; 解释&#xff1a; B2表格的公式&q…

C++面试宝典第17题:找规律填数

题目 仔细观察下面的数字序列,找到规律,并填写空白处的数字。 (1)1, 2, 4, 7, 11, 16, __ (2)-1, 2, 7, 28, __, 126 (3)6, 10, 18, 32, 57, __ (4)19, 6, 1, 2, 11, __ (5)2, 3, 5, 7, 11, __ (6)1, 8, 9, 4, __, 1/6 (7)1, 2, 3, 7, 16, __, 321 (8)1, 2, …

【Kubernetes】如何使用 kubectl 操作 cluster、node、namespace、pod

如何使用 kubectl 操作 cluster、node、namespace、pod 在列出、描述、修改或删除其他命名空间中的对象时&#xff0c;需要给 kubectl 命令传递 --namespace&#xff08;或 -n&#xff09;选项。如果不指定命名空间&#xff0c;kubectl 将在当前上下文中配置的默认命名空间中执…

java进阶||jdk进阶之循环

从18年学java到现在除了各种各样的数据类型和集合烧不了要遍历这些变量, for循环这时就少不了啦(当然还有8后引入的神器泛型) 先来看一段精髓业务代码, 使用了多个新特性当然也少不了循环和分支判断 代码较长解析在后面 private CommonPage<List<Object>> handle…

Apache Doris (六十二): Spark Doris Connector - (2)-使用

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. 将编译jar包加入本地Maven仓库

【重学C语言】一、C语言简介

【重学C语言】一、C语言简介 什么是编程语言&#xff1f;编程语言 C语言发展史C语言标准变迁开发软件CLion安装步骤 VIsual Studio安装步骤 Clion 和 VS2022 绑定 电脑常识 什么是编程语言&#xff1f; 人类语言&#xff1a;语言就是人类进行沟通交流的表达方式&#xff0c;应…

【小工具】pixi-live2d-display,直接可用的live2d的交互网页/桌面应用

效果&#xff1a; <script src"https://cubism.live2d.com/sdk-web/cubismcore/live2dcubismcore.min.js"></script> <script src"https://cdn.jsdelivr.net/gh/dylanNew/live2d/webgl/Live2D/lib/live2d.min.js"></script> <…

【Android Studio】APP练手小项目——切换图片APP

本项目效果&#xff1a; 前言&#xff1a;本项目最终实现生成一个安卓APP软件&#xff0c;点击按钮可实现按钮切换图片。项目包含页面布局、功能实现的逻辑代码以及设置APP图标LOGO和自定义APP名称。 关于Android Studio的下载与安装见我的博文&#xff1a;Android Studio 最新…

v-if控制div内容显示,克隆这个div但是v-if没有效果

问题描述&#xff1a; 我的子页面打印的时候通过isPdf来隐藏“选择参加人员”按钮。 我子页面有个el-dialog&#xff0c;el-dialog里面有个大的div它的id为app-pre-meet-add&#xff0c;在子页面我通过isPdf来显示我想要的内容。现在我在父页面先通过this.$refs.child.control…

服务器组网方案

在当今数字化时代&#xff0c;服务器组网方案不仅是企业信息管理的关键&#xff0c;更是支撑业务运作的核心架构 。为了实现高效的数据处理和存储&#xff0c;服务器组网方案成为企业不可或缺的一部分。本文将深入探 讨服务器组网方案的核心要素和实施策略&#xff0c;明确其在…

Spring boot 3 集成rocketmq-spring-boot-starter解决版本不一致问题

安装RocketMQ根据上篇文章使用Docker安装RocketMQ并启动之后&#xff0c;有个隐患详情见下文 Spring Boot集成 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2…

001 Golang-channel-practice

最近在练习并发编程。加上最近也在用Golang写代码&#xff0c;所以记录一下练习的题目。 第一道题目是用10个协程打印100条信息&#xff0c;创建10个协程。每个协程都会有自己的编号。每个协程都会被打印10次。 package mainimport ("fmt""strconv" )func …

MS3814:DVI/HDMI TMDS FR-4 和电缆均衡器/驱动器

产品简述 MS3814 是一款 TMDS 均衡 / 驱动器芯片&#xff0c;用于补偿 FR-4 和 电缆到 DVI/HDMI 连接器的损耗。提供完全满足 DVI/HDMI TMDS 要求的输出。芯片还可用于 DVI/HDMI 电缆以延长传输距离&#xff0c;提 高连接器接收侧电缆通道的抖动余量。片上 TMDS…

控制台项目和ASP.Net Core 1.项目创建 2.一键启动多个服务 3.引入别的库

感悟&#xff1a; 1.注意选择&#xff1a;.NET/.Net Core下面的控制台或者ASP.NET Core web应用&#xff0c;而且只有.net core的项目是跨平台的&#xff0c;选错的话&#xff0c;是无法发布到linux上的。 2.c#的命名空间和java包的区别&#xff1a; c#中是按照包来的&#x…

达梦数据库的归档模式介绍

几种归档模式 归档是实现数据守护系统的重要技术手段&#xff0c;根据功能与实现方式的不同&#xff0c;DM 数据库的归档可以分为 6 类&#xff1a;本地归档、远程归档、实时归档、即时归档、异步归档和同步归档。 其中&#xff0c;本地归档日志的内容与写入时机与数据库模式…

SpringBoot-开启Admin监控服务

SpringBoot-Admin是一个用于管理和监控SpringBoot应用程序的开源项目。它提供了一个易于使用的Web界面&#xff0c;可以实时监控应用程序的健康状况、性能指标、日志和环境配置等信息。通过Actuator模块来收集和暴露应用程序的监控信息&#xff0c;使用Web Socket或者Server-Se…

苹果电脑RAW图像处理软件Capture One Pro 22 mac软件介绍

Capture One Pro 22 for mac是一款专业的RAW文件转换器和图像编辑软件&#xff0c;拥有更新的处理引擎、市场领先的性能和强大的新功能&#xff0c;可为 500 多台高端相机提供具有美丽色彩和令人难以置信的细节的终极图像质量。 Capture One Pro 22 for Mac版软件介绍 Capture…

qt打包完整详细过程 包你成功

找问题找了一个多小时&#xff0c;不停调试&#xff0c;还修改文件路径&#xff0c;配置路径&#xff0c;开机关机&#xff0c;最后终于做出来了&#xff0c;得出来了一个结论 我绝对是天才 首先 看这个视频 k14 打包发布_哔哩哔哩_bilibili 不出意外&#xff0c;你绝对会在…