计算机操作系统实验之模拟进程管理(C语言)

这篇博客记录了一次计算机操作系统实验,通过C语言模拟实现进程的创建、查看、换出、杀死等功能。实验旨在理解进程概念,掌握进程控制,并通过进程控制块(PCB)管理进程状态。文中详细介绍了实现思路,包括使用两个链表分别表示执行和阻塞状态的进程,并提供了部分源代码文件名。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这星期开始上计算机操作系统的实验课,打算把每个实验的内容和思路记录一下

实验目的

1、 理解进程的概念,明确进程和程序的区别。

2、 理解并发执行的实质。

3、 掌握进程的创建、睡眠、撤销等进程控制方法。

实验内容与基本要求

用C,C++等语言编写程序,模拟实现创建新的进程;查看运行进程;换出某个进程;杀死进程等功能。

实验报告内容

1.进程、进程控制块等的基本原理

a.为了能使程序并发执行,并且可以对并发执行的程序加以描述和控制,引入了“进程”的概念。它是资源分配和独立运行的基本单位。

b.进程控制块(PCB)是操作系统为进程配置的一个专门的数据结构。系统利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。

进程PCB可以包含

/*
|进程ID|
|进程优先级|
|进程大小(进程执行时间|
|进程内容|
|进程状态|
|指针|
*/

2.进程过程图

img_1

以传统菜单的形式呈现功能。

1.创建新的进程 2.查看运行进程”

3.换出某个进程 4.杀死运行进程”

5.唤醒某个进程 6.退出程序 “

实现思路及功能分析

系统利用进程控制块(Process Control Block,PCB)来描述系统的基本情况和活动过程,要进行进程管理,实际上就是在操作进程的PCB。因此要求模拟进程管理,首先要模拟出PCB的结构,再实现它的创建、撤销等操作。

一般来说,进程拥有三种基本状态:就绪、执行、阻塞。在引入了挂起原语操作后,还会细分为活动就绪、静止就绪、活动阻塞、静止阻塞。在我的理解中,活动与静止的区别就是,活动时进程是在主存中的,而静止时进程已经被调到了辅存里。

在单处理机系统中,只有一个进程处于执行状态,而在多处理机系统中,能有多个进程处于执行状态。因此在这里我们不将执行状态与就绪状态特别区分开来,只设置两个链表,一个链表用于保存处于执行(或就绪)状态的进程,一个链表用于保存处于阻塞状态的进程。

当然,如果想模拟单处理机系统的话,也可以将处于就绪状态链表的第一个结点默认设置为执行状态,当有优先度更高的进程时,让它成为执行状态,插入链表头部,原有的第一个结点转为就绪状态即可。但是本实验中不涉及优先级调度的算法,所以就简化处理了。

同样,我们模拟内存的大小,例如理论上可以同时运行20个进程,那么将处于执行状态的进程转为阻塞状态时,可以看做把它转移到了辅存中。但是不区分活动阻塞、静止阻塞,只是简单地设置成运行进程个数的变化。

总的来说,我们这次试验的思路是

  • 设置两个单链表,一个用于存储运行的进程,一个用于存储阻塞状态的进程
  • 默认内存中可以存放最多20个进程,将处于运行队列的进程看作在内存中,阻塞状态不在内存中
  • 进程创建,则去申请内存空间,填写完进程信息后直接加入运行队列
  • 杀死进程,则将进程从运行队列中删除,并直接释放
  • 进程的换出与唤醒,就是让进程在运行队列与阻塞队列之间转换(进程自己的状态也发生改变)
  • 为了操作简便,额外写了几个辅助函数来使用

流程图

img_2

全部代码

工程图

img_2

ProcessControl.h
//
//  ProcessControl.h
//  ProcessControlTest
//
//  Created by Apple on 2019/10/13.
//  Copyright © 2019 Yao YongXin. All rights reserved.
//

#ifndef ProcessControl_h
#define ProcessControl_h

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//最大内存的大小
#define MAX_SIZE 20

//线程状态:运行(就绪)  阻塞
enum process_type{
   
    process_type_running = 1000,
    process_type_block = -1000,
    process_type_ready = 500
};

//进程控制块结构体
typedef struct PCB_Type{
   
    //进程的id
    int pid;
    //进程的优先级
    int priority;
    //进程大小(执行时间)
    int size;
    //进程内容
    char content[20];
    //进程的状态  执行  阻塞
    int state;
    //下一个要执行的进程
    struct PCB_Type *next;
}PCB;

//创建新的进程
void create(PCB *running_list,PCB *block_list,int *size);
//查看运行进程
void show_running(PCB *running_list);
//换出某个进程
void change(PCB *running_list,PCB *block_list,int *size);
//杀死运行进程
void killed(PCB *running_list,int *size);
//唤醒某个进程
void wake_up(PCB *running_list,PCB *block_list,int *size);

//判断在运行(就绪)队列中是否存在有该pid值的进程 0->不存在 1->存在
int exist_in_running(PCB *running_list,int pid);
//判断在阻塞队列中是否存在有该pid值的进程 0->不存在 1->存在
int exist_in_block(PCB *block_list,int pid);
//通过pid寻找进程的位置(返回其前一个结点的地址
PCB *find(PCB *list,int pid);

#endif /* ProcessControl_h */
ProcessControl.c
//
//  ProcessControl.c
//  ProcessControlTest
//
//  Created by Apple on 2019/10/13.
//  Copyright © 2019 Yao YongXin. All rights reserved.
//

#include "ProcessControl.h"

//创建新的进程
void create(PCB *running_list,PCB *block_list,
(1) 进程的创建编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。(2) 进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。(3) 编制一段程序,使其实现进程的软中断通信。要求:使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程调用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process 1 is killed by parent! Child process 2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 在上面的程序中增加语句signal(SIGINT, SIG_IGN)和 signal(SIGQUIT, SIG_IGN),观察执行结果,并分析原因。(4) 进程的管道通信编制一段程序,实现进程的管道通信。使用系统调用pipe( )建立一条管道线;两个进程P1和P2分别向管道各写一句话: Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值