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


一、实验目的

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

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
进程间通信是指在不同进程之间进行数据交换和同步的一种技术。Linux提供了多种进程间通信的方式,包括管道、消息队列、共享内存和信号量等。在实验六中,我们将学习如何使用这些方式进行进程间通信。 1. 管道 管道是一种半双工的通信方式,它可以在两个进程之间传递数据。在Linux中,管道分为匿名管道和命名管道。匿名管道只能用于父子进程之间的通信,而命名管道可以用于任意两个进程之间的通信。 使用匿名管道进行进程间通信的步骤如下: - 父进程创建管道,并调用fork函数创建子进程。 - 子进程通过管道接收数据。 - 父进程通过管道发送数据。 - 子进程接收到数据后进行处理。 使用命名管道进行进程间通信的步骤如下: - 创建命名管道。 - 打开命名管道并进行读写操作。 2. 消息队列 消息队列是一种进程间通信机制,它允许不同进程之间通过一个消息传递序列来进行通信。在Linux中,每个消息都有一个类型,接收进程可以选择接收某个特定类型的消息。 使用消息队列进行进程间通信的步骤如下: - 创建消息队列。 - 发送消息到消息队列。 - 接收消息并进行处理。 3. 共享内存 共享内存是一种进程间通信的方式,它允许不同进程之间共享同一个物理内存区域。这种方式比较高效,但需要考虑进程间的同步和互斥问题,否则会出现数据不一致的情况。 使用共享内存进行进程间通信的步骤如下: - 创建共享内存区域。 - 进程通过共享内存区域进行数据交换。 - 进程需要进行同步和互斥操作。 4. 信号量 信号量是一种进程间同步的机制,它可以用来保证不同进程之间的共享资源在同一时刻只能被一个进程访问。在Linux中,每个信号量都有一个计数器,当计数器为0时,进程需要等待;当计数器大于0时,进程可以继续执行。 使用信号量进行进程间通信的步骤如下: - 创建信号量。 - 进程对信号量进行P操作(等待)。 - 进程对信号量进行V操作(释放)。 总体来说,不同的进程间通信方式各有优缺点,应根据实际需求选择适合的方式。在实验六中,我们将通过编写代码来学习如何使用这些方式进行进程间通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Francek Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值