操作系统 实验二 进程与进程通信

操作系统 实验二 进程与进程通信

摘要

在本试验 PART1 中设计了一个程序,该程序创建一个子进程,使父子进程合作,协调地完成收发信号、打印目录功能。在该程序中使用了进程的睡眠、进程图象改换、父进程等待子进程终止、信号的设置与传送(包括信号处理程序)、子进程的终止等有关进程的系统调用。在本试验 PART2 中,分别利用 UNIX 的消息通信机制、共享内存机制(用信号灯实施进程间的同步和互斥)实现两个进程间的数据通信与简单的信息处理。

算法思想和概要设计

算法思想

PART1

父进程设置信号 SIGUSR1 的信号处理函数,子进程继承父进程的信号处理方式。子进程创建后进入 10 s 10s 10s 的低优睡眠;父进程先打印相关信息,在发送软中断信号前先进入 1 s 1s 1s 的低优睡眠,防止在子进程进入睡眠前就发送信号。父进程完成睡眠后将软中断信号传送给子进程,唤醒低优睡眠中的子进程,触发自定义的信号处理程序。之后子进程正常运行,执行图像改换,列出当前路径下的目录。父进程等待子进程终止。

PART2
消息通信

本部分分为 Server 进程和 Client 进程两个进程。ServerClient 通过同一个关键字获得相同消息队列的标识符。之后 Client 通过消息通信向 Server 发送信息,内容为自己的进程号,并接收 Server 通过消息通信返回的信息。Server 保持监听消息队列,收到 Client 发送的消息后就打印出来,并将消息经过一定处理后返回 Client

共享内存

父进程创建 1 k b 1kb 1kb 大小的共享内存与同步信号灯组,得到共享内存标识符与信号灯组标识符。父进程把共享内存连接到当前进程的地址空间。由于本部分只有两个进程,所以任一信号灯的信号量不可能超过 1 1 1 ,因此信号灯组只需要两个信号灯,不需要互斥信号灯。信号灯组含读与写两个信号灯,写信号灯初始化为 1 1 1 ,读信号灯初始化为 0 0 0 。然后父进程创建子进程,子进程继承之前所述参数。之后父进程向共享内存中输入信息,子进程从共享内存中读出并处理信息,完成父子进程间的共享内存通信。

概要设计

以下将以流程图来展示对该程序分配与释放内存的过程概要设计。

PART1

在这里插入图片描述

PART2
消息通信

在这里插入图片描述

共享内存

在这里插入图片描述

数据结构与变量说明

消息缓冲区

struct msgtype{
   
    long mtype;		// 消息类型
    int text;			// 消息正文
};

信号灯组

typedef	union semunion{
   
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux specific) */
}semunion;

源程序

PART1

主程序
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>

int main(){
   
    int status;
    pid_t pid;
    void func();
    signal(SIGUSR1, func);				// 设置信号SIGUSR1的中断处理函数为func
    while((pid = fork()) == -1);	// 产生子进程
    if(pid){
   											// 父进程
        printf("It is the parent process.\n");
        printf("Parent: will send signal.\n");
        sleep(1);								// 向子进程传送信号前先睡眠一秒,保证信号到达时子进程正在低优睡眠中
        kill(pid, SIGUSR1);			// 父进程向子进程传送SIGUSR1软中断信号
        pid = wait(&status);		// 父进程等待子进程终止
        printf("Child process %d, status = %d.\n", pid, status);
    }
    else{
   													// 子进程
        sleep(10);
        printf("It is the child process.\n");
        printf("Child: signal is received.\n");
				execl("/bin/ls", "ls", "-l", (char*)0); // 进程图像改换,将子进程图像改换为ls命令
        printf("execl error\n");								// 图像改换失败
        exit(2);
    }
    printf("Parent process finish.\n");
}

void func(){
   		// 自己设置的信号SIGUSR1的中断处理函数
    printf("It is a signal processing function.\n");
    system("date")
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值