Linux实验五:进程间通信(一)

目录

    • 一、实验目的
    • 二、实验内容
    • 三、实验环境
    • 四、参考代码
    • 五、实验步骤
      • 步骤1. 编辑源代码test5.c
      • 步骤2. 编译源代码test5.c
      • 步骤3. 运行可执行程序test5
      • 步骤4. 进一步调试源代码test5.c
    • 六、实验结果
    • 七、实验总结


一、实验目的

1、理解Linux进程通信的基本原理和方法;
2、掌握进程间的管道通信编程;
3、掌握进程间的内存共享编程;
4、掌握进程间队列通信编程,信号量和消息队列。

二、实验内容

通过创建两个进程并通过共享内存、信号量和消息队列进行通信,实现进程间的数据传输和同步。在代码中,父进程创建共享内存段、信号量和消息队列,并传递给子进程。子进程从共享内存中读取数据并将其发送到消息队列,父进程从消息队列中接收数据并写入共享内存。通过这种方式,实现了进程间的通信和同步。

三、实验环境

虚拟机软件:VMware 16 Pro
Linux操作系统版本:CentOS-7-64位

四、参考代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<sys/time.h>

#define oops(s,x) {perror(s);exit(x);}

void sig_handle(int signo);

int main(int argc,char* argv[])
{
    struct itimerval value,old_value;

    signal(SIGALRM,sig_handle);
    signal(SIGINT,sig_handle);

    value.it_value.tv_sec=1;
    value.it_value.tv_usec=0;
    value.it_interval.tv_sec=1;
    value.it_interval.tv_usec=0;

    setitimer(ITIMER_REAL,&value,&old_value);

    while(1)
    {
        sleep(5);
        printf("Current process is running...\n");
    }
    return 0;
}

void sig_handle(int signo)
{
    switch(signo){
        case SIGALRM:
            printf("It's time now!\n");
            break;
        case SIGINT:
            oops("SIGINT has been catched!",-1);
            break;
    }
    return;
}

五、实验步骤

步骤1. 编辑源代码test5.c

源代码test5.c内容见上述参考代码。

mkdir test5
cd test5
vim test5.c

在这里插入图片描述

  • signal(SIGALRM, sig_handle);signal(SIGINT, sig_handle);这两行设置了信号处理函数。当程序接收到SIGALRMSIGINT信号时,将调用sig_handle函数进行处理。
  • setitimer(ITIMER_REAL, &value, &old_value);这行设置了一个实时定时器。它会定时发送SIGALRM信号。value.it_value.tv_secvalue.it_interval.tv_sec分别设置了定时器的初始值和间隔值。
  • while(1) { sleep(5); printf("Current process is running...\n"); }这是一个无限循环,每次循环会让程序休眠 5 秒,并打印一条消息表示当前进程正在运行。
  • sig_handle函数是一个信号处理函数。当接收到SIGALRM信号时,它会打印 “It’s time now!”;当接收到SIGINT信号时,它会输出一个错误信息并退出程序。

步骤2. 编译源代码test5.c

gcc test5.c -o test5 -g

在这里插入图片描述

步骤3. 运行可执行程序test5

./test5

在这里插入图片描述

步骤4. 进一步调试源代码test5.c

(1)将宏定义#define oops(s,x),改写成函数形式,并将函数名定义为“自己姓名拼音”,参数保持不变。

void zhc(char* strs,int num)
{
    perror(strs);
    exit(num);
}

(2)程序收到SIGALRM信号后,额外再输出自己的学号。

case SIGALRM:
	printf("It's time now! 学号:123456789\n");
	break;

(3)程序收到SIGINT信号后,额外再输出自己的姓名。

case SIGINT:
	zhc("SIGINT has been catched! 姓名:zhc",-1);
	break;

再重新编译test5.c,并运行可行性文件test5。结果如下图所示:

在这里插入图片描述

六、实验结果

调试后的最终源代码test5.c:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<sys/time.h>

void zhc(char* strs,int num)
{
    perror(strs);
    exit(num);
}

void sig_handle(int signo);

int main(int argc,char* argv[])
{
    struct itimerval value,old_value;

    signal(SIGALRM,sig_handle);
    signal(SIGINT,sig_handle);

    value.it_value.tv_sec=1;
    value.it_value.tv_usec=0;
    value.it_interval.tv_sec=1;
    value.it_interval.tv_usec=0;

    setitimer(ITIMER_REAL,&value,&old_value);

    while(1)
    {
        sleep(5);
        printf("Current process is running...\n");
    }
    return 0;
}

void sig_handle(int signo)
{
    switch(signo){
        case SIGALRM:
            printf("It's time now! 学号:123456789\n");
            break;
        case SIGINT:
            zhc("SIGINT has been catched! 姓名:zhc",-1);
            break;
    }
    return;
}

实验运行结果如下图所示。

在这里插入图片描述

七、实验总结

  在进行了基于Linux进程通信的实验后,我对进程间通信有了更深入的理解和掌握。通过实验中的代码示例,我深入了解了共享内存、信号量和消息队列等进程间通信的基本原理和实现方式。
  首先,我对共享内存有了更清晰的认识。在实验中,我学会了如何使用共享内存来实现两个进程之间的数据共享。通过创建共享内存段,并在父子进程之间传递共享内存的标识符,实现了数据在进程间的共享和传递。这种高效的数据共享方式使得进程间的通信更加快速和便捷。
  其次,我学习了如何使用信号量进行进程间的同步控制。在实验中,我使用信号量来保护共享资源,防止多个进程同时访问造成数据不一致的问题。通过对信号量的初始化、增减和释放等操作,实现了对临界区的互斥访问和同步操作,确保了进程间数据的正确性和一致性。
  最后,我深入了解了消息队列的使用方法及其在进程通信中的应用。通过创建消息队列,我成功实现了进程间的异步通信。子进程将数据发送到消息队列,父进程从消息队列中接收数据并进行处理,实现了进程间的解耦和异步通信,提高了系统的灵活性和可扩展性。
  通过这次实验,我不仅学会了如何使用Linux系统提供的进程通信机制,还进一步加深了对操作系统原理的理解。我相信这些在实验中学到的知识和经验将对我的后续学习和工作有着重要的指导作用,帮助我更好地理解和应用进程通信相关的知识。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

刷题之从前序遍历与中序遍历序列构造二叉树(leetcode)

从前序遍历与中序遍历序列构造二叉树 前序遍历&#xff1a;中左右 中序遍历&#xff1a;左中右 前序遍历的第一个数必定为根节点&#xff0c;再到中序遍历中找到该数&#xff0c;数的左边是左子树&#xff0c;右边是右子树&#xff0c;进行递归即可。 #include<vector>…

基于微信的家庭理财管理小程序的设计与实现(论文+源码)_kaic

摘 要 随着中国经济的飞速发展&#xff0c;家庭收入不断增高&#xff0c;人们的消费除了简单的维持日常生活之外&#xff0c;还有其他的消费方式&#xff0c;比如旅游、电商购物等&#xff0c;层出不穷的消费方式带给人快乐的同时&#xff0c;也常常让一些人逐渐无法把握住自…

【算法】栈算法——最小栈

题解&#xff1a;最小栈(栈算法) 目录 1.题目2.题解3.总结 1.题目 题目链接&#xff1a;LINK 这个题目题意说的有点绕&#xff0c;说白了让你在常数时间内检索到最小元素就是O(1)时间复杂度下找到栈中最小的元素。 2.题解 思路&#xff1a;这个栈可以内嵌套两个库栈来进行…

了解区块链基础设施,共同构建安全且强大的Sui网络

区块链基础设施的范畴很广&#xff0c;但其核心是那些直接与网络互动的计算机。这些实体通常被称为节点&#xff0c;分为不同的类型&#xff0c;例如维护完整区块链副本的全节点&#xff0c;以及作为共识决定者的验证节点。除了这两种类型之外&#xff0c;还有其他类型的节点&a…

蓝牙(2):BR/EDR的连接过程;查询(发现)=》寻呼(连接)=》安全建立=》认证=》pair成功;类比WiFi连接过程。

4.2.1 BR/EDR 流程&#xff1a; 查询&#xff08;发现&#xff09;》寻呼&#xff08;连接&#xff09;》安全建立》认证》pair成功 4.2.1.1 查询&#xff08;发现&#xff09;流程Inquiry (discovering) 类比WiFi的probe request/response 蓝牙设备使用查询流程来发现附近的…

Solidity的引用类型全解析

引用的本来语意 引用类型&#xff0c;变量本身与变量指向的数据分离&#xff0c;赋值操作是引用拷贝&#xff0c;数据块不受影响通常的面向对象语言中的所有引用类型变量之间的赋值操作&#xff0c;都是引用拷贝这一点在Solidity的引用类型中不再成立&#xff0c;solidity的引…

二叉数之插入操作

首先是题目 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效…

防火墙技术基础篇:基于IP地址的转发策略

防火墙技术基础篇&#xff1a;基于IP地址的转发策略的应用场景及实现 什么是基于IP地址的转发策略&#xff1f; 基于IP地址的转发策略是一种网络管理方法&#xff0c;它允许根据目标IP地址来选择数据包的转发路径。这种策略比传统的基于目的地地址的路由更灵活&#xff0c;因…

HTML静态网页成品作业(HTML+CSS)——川西旅游介绍网页(2个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有2个页面。 二、作品演示 三、代…

CentOS 7安装prometheus

说明&#xff1a;本文介绍如何在CentOS操作系统上安装prometheus Step1&#xff1a;下载安装包 访问Github仓库&#xff0c;下载对应版本的prometheus安装包 https://github.com/prometheus/prometheus/releases 操作系统的版本信息&#xff0c;可通过下面这两个命令查看&am…

反编译抖音 a_bogus vmp

接上篇的继续 反编译 vmp 来进行学习 抖音的不太一样的点在于 他的vmp代码是分散的 好几段代码都是vmp的 然后指令对应的操作还不一样 就很蛋疼… 而且 指令对应的操作也是if else 还有三元表达式形式的 不太好找位置 第一步 看vmp代码结构 484e4f4a403f524300033604d6dbeab…

kafka监控配置和告警配置——筑梦之路

kafka_exporter项目地址&#xff1a;https://github.com/danielqsj/kafka_exporter docker-compose部署kafka_exporter # docker-compose部署多个kafka_exporter&#xff0c;每个exporter对接一个kafka# cat docker-compose.ymlversion: 3.1 services:kafka-exporter-opslogs…

30.标签实现动画

SVG的<set>标签是一个非常有用的工具&#xff0c;它允许开发者在SVG图形中创建简单的动画效果。这个标签主要用于在一段时间内改变一个属性到一个新值。以下是关于如何使用<set>标签的一些详细说明和示例。 <set>标签的基本用法 <set>标签用于在SVG动…

【代码随想录】【算法训练营】【第17天】 [110]平衡二叉树 [257]二叉树的所有路径 [404]左叶子之和

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 17&#xff0c;又是一个令人愉快的周五~ 题目详情 [110] 平衡二叉树 题目描述 110 平衡二叉树 解题思路 前提&#xff1a;平衡二叉树&#xff1a;左右子树高度差不超过1, 思路&#xff1a;…

Fastjson漏洞之CVE-2017-18349

前言&#xff1a; 要想理解漏洞原理&#xff0c;首先看看Fastjson是什么&#xff0c;具体用来做什么才能更好的找到可以利用的场景&#xff1a; Fastjson 是一个由阿里巴巴开发的 Java 语言实现的高性能 JSON 解析器和生成器。它具有以下特点: 快速&#xff1a;Fastjson 在序列…

【区块链】caliper压力测试

本文上接postman接口测试 参照工程项目使用Caliper测试工具对食品安全溯源系统智能合约生成新食品(newFood)功能进行压力测试 首先启动webase python3 deploy.py startAll vim /opt/bencahmark/caliper-benchmark/networks/fisco-bcos/test-nw/fisco-bcos.json 命令便捷查…

LLama3 | 一. 本地 Web Demo 部署

前置工作 课程文档&#xff1a;Llama3-Tutorial/docs/hello_world.md at main SmartFlowAI/Llama3-Tutorial GitHub 1.安装vscode 2.安装vscode插件 Remote SSH 3.配置 VSCode 远程连接开发机 ssh连接开发机 进行端口映射 在开发机控制台中点击自定义服务&#xff0c;复…

Python编程之旅:从错误到精通的奇妙探险

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、初识Python编程的陷阱与解决方案 1. 语法错误&#xff1a;防范于未然 2. 逻辑错误&…

java+Angular+Nginx+原生HTML+JS+CSS+Jquery融合B/S版电子病历系统云HIS系统源码

javaAngularNginx原生HTMLJSCSSJquery融合B/S版电子病历系统云HIS系统源码 Java版云HIS系统融合电子病历系统&#xff0c;是医学专用软件。医院通过电子病历以电子化方式记录患者就诊的信息&#xff0c;包括&#xff1a;首页、病程记录、检查检验结果、医嘱、手术记录、护理记录…

Day24:Leetcode:235. 二叉搜索树的最近公共祖先 + 701.二叉搜索树中的插入操作 + 450.删除二叉搜索树中的节点

LeetCode&#xff1a;235. 二叉搜索树的最近公共祖先 解决方案&#xff1a; 1.思路 对于当前节点x&#xff0c;如果x比p和q的值都大&#xff0c;说明&#xff0c;p和q在x的右子树里面&#xff0c;那么去x的右子树里面去寻找&#xff1b;对于当前节点x&#xff0c;如果x比p和…