首页 > 系统相关 >Linux实验五:进程间通信(一)

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

时间:2024-05-25 10:26:08浏览次数:25  
标签:handle SIGINT value 间通信 sig Linux 进程 test5

目录


一、实验目的

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系统提供的进程通信机制,还进一步加深了对操作系统原理的理解。我相信这些在实验中学到的知识和经验将对我的后续学习和工作有着重要的指导作用,帮助我更好地理解和应用进程通信相关的知识。

标签:handle,SIGINT,value,间通信,sig,Linux,进程,test5
From: https://blog.csdn.net/Morse_Chen/article/details/139167464

相关文章

  • 【Linux】icmp_seq=1 Destination Host Unreachable
    执行ping命令提示:From192.168.XX.XX  icmp_seq=1DestinationHostUnreachable这个错误消息通常表示以下几种情况之一:网络连接问题:目标主机可能没有连接到网络,或者网络中的某个路由器无法将数据包转发到目标主机。目标主机不存在:目标主机的IP地址可能不存在,或者......
  • 进程间的通信
    进程间的通信方式有哪些?管道,消息队列,共享内存,信号量,信号。管道管道分为匿名管道和命名管道。匿名管道$psauxf|grepmysql上面命令行里的「|」竖线就是一个管道,它的功能是将前一个命令(psauxf)的输出,作为后一个命令(grepmysql)的输入,从这功能描述,可以看出管道传输......
  • 在Linux下管理MySQL的大小写敏感性
    当开发与Linux环境下MySQL数据库交互的Java应用程序时,理解MySQL中的大小写敏感性可以避免潜在的错误和问题。本指南深入探讨了MySQL中的大小写敏感设置,比较了5.7和8.0版本,并为Java开发者提供了最佳实践。1理解MySQL中的大小写敏感性默认情况下,MySQL在Windows上是大小写不敏感的......
  • linux学习笔记---系统时间和文件类命令
    1、主机的系统时间配置1)查看主机系统时间datedate'+%Y-%m-%d'date'+%Y-%m-%d:%H:%M:%S'2)更改(设置)系统时间date-sdate-s'2023-12-1212:12:12'3)如何将时间更改回来?方法一:Linux硬件的时间的设置hwclock设置系统硬件时间:hwclock--set--date'2024052......
  • linux内核初始化阶段-fork内嵌问题
    目录1.在linux内核初始化程序中fork需要_syscall0(int,fork)的背景1.1.背景1.2.重点来了-为啥需要_syscall0(int,fork)2.内联函数+宏定义的作用3.参考1.在linux内核初始化程序中fork需要_syscall0(int,fork)的背景1.1.背景内核的main中线进行了所有硬件初始化工作,包括陷阱......
  • 基于Python的性能优化--多线程、协程、多进程
    合集-Python(1) 1.基于Python的性能优化05-24收起 一、多线程在CPU不密集、IO密集的任务下,多线程可以一定程度的提升运行效率。importthreadingimporttimeimportrequestsdeffetch_url(url:str)->None:'''根据地址发起请求,获取响应-url:......
  • 手把手教你编译属于自己的内核--->WSL-Linux子系统编译安装内核教程
    准备步骤前言:文章操作wsl子系统为ubuntu1.到LINUX内核官网下载最新版的内核Linux内核官网:Linux内核官网点击黄色按钮即可下载最新版本内核解压tarxvJflinux-6.9.1.tar.xz2.使用gitclone到github下载WSL2内核源码到终端输入​sudogitclone https://github.com/......
  • Linux Xorg与Vsync不兼容,使用独显启动,在外置显示器上有时会卡死
    https://www.vsynctester.com/https://forums.developer.nvidia.com/t/bug-having-two-monitor-connected-x11-causes-initial-stutter-when-opening-steam/278749https://www.reddit.com/r/linux_gaming/comments/tdt1gx/looking_for_people_having_stutter_issues_with/h......
  • Linux应用——进程基础
    谁来调用main函数在运行main函数之前,会有一段引导代码,最终由这段代码调用main函数,这段引导代码不需要自己编写,而是在编译、链接中由链接器将这段程序链接到应用程序中,构成最终的可执行文件,加载器会将可执行文件加载到内存中进程的终止正常终止在main函数中通过retur......
  • [Linux] 进程概念
    目录1.冯诺依曼硬件体系结构2.操作系统(OS)3.系统接口4.进程的概念5.进程状态6.四个其他概念7.环境变量8.进程地址空间1.冯诺依曼硬件体系结构在冯诺依曼体系结构中,计算机是由输入、输出、存储设备和中央处理器cpu组成的。图中体结构的存储器专指内存,内存......