进程创建与撤销的模拟实现

本文档描述了一个操作系统进程管理的模拟实现,包括进程创建、优先级排序、显示和终止等功能。通过创建一个数据结构PCB,实现了就绪队列,并使用冒泡排序对进程按优先级排序。同时,提供了用户交互菜单,允许用户执行各种操作,如创建新的进程、查看就绪队列、终止进程等。代码中详细解释了每个函数的功能和实现过程。
摘要由CSDN通过智能技术生成

总体设计

  • 数据结构定义:
    结构体PCB:进程名、ID、运行时间、优先级等,队列的排序按优先级排序。
    PCB空间:结构体PCB数组
    就绪队列指针
    首尾指针
  • 函数
    InitQueue():初始化就绪队列
    Create()—进程创建:从PCB空间申请一个空PCB,填入进程参数,插入就绪队列;
    kill()—进程终止:将指定的就绪进程移出就绪队列,清除PCB中的信息;
    display()—就绪队列输出函数:输出就绪队列中的进程信息,以便观察创建或撤消活动的结果;
    Sort()—进程优先级排序,根据你定义的优先级,把进程进行排序。
    menu()—功能选择:调用创建函数;调用终止函数;显示就绪进程;退出系统等。
  • 功能测试:
    在菜单中选择执行各功能,从显示出的就绪队列状态,查看操作的正确与否。

详细设计

在本次模拟实验中,我主要写了六个函数。

——在InitQueue()中,我主要将指向就绪队列的头指针和尾指针初始化,方便后面进程的创建。
——在Create()函数中,我主要将要创建的进程的参数填入PCB,并插入到就绪队列中。在Create()函数中我进行了三次判断,第一次是n是否大于100,如果n>100,说明PCB数组已满(即模拟内存已满)就不能再继续创建进程了,反之可以;第二次是判断L.front->next是否为NULL,如果为NULL,说明这时创建的进程是系统中第一个进程,不用考虑进程id是否会与其他进程id重复,可直接将参数填入数组,反之我们就要判断id是否会与其他进程id重复,即第三次判断,如果id重复,我们就要重新输入,直至成功为止,然后将填入参数的PCB节点插入到就绪队列中,即进程创建成功。
—— Sort()函数主要是对进程的优先级进行排序,这里我采用了冒泡排序将优先级高的进程放在了就绪队列的前面。
——display()函数主要是输出当前就绪队列中的所有就绪队列的信息,我们可以借助这个函数来查看我们的每一次操作是否成功。
——kill()函数主要是用来终止进程,我们进行进程的终止操作是将进程移出就绪队列,重新找到首位指针应该指向的位置,并且删除已终止的进程在PCB中的相关信息。
——menu()是菜单函数,让我们进行功能选择,我们可以从菜单中选择调用上述的任一函数,从而进一步对进程的创建与撤销进行操作。

代码实现

#include <stdio.h>
#include <stdlib.h>
///pcb控制块信息
typedef struct P_node{
    char t_name[20];///进程名
    long t_id;///进程id
    float t_time;///进程运行时间
    int priority;///进程优先级
}PCB;
///就绪队列
typedef struct Tnode *T;
struct Tnode{
    int data;
    T next;///指向就绪队列的下一个位置
};
///消息缓冲队列
typedef struct Linkqueue{
    T front,rear;///头指针和尾指针分别指向就绪队列的头和尾
}LQ;
LQ L;
PCB pcb[100];///结构体PCB数组,模拟当前内存大小
int N=0;///当前已经创建的进程数目
///就绪队列初始化
void InitQueue(){
    L.rear=L.front=malloc(sizeof(T));
    if(!L.front)
        exit(-2);
    L.front->next=NULL;
    return 0;
}
///创建进程:申请PCB,填入进程参数
void Create(){
    int n;///要创建的进程的数目
    printf("请输入要创建的进程的数目:");
    scanf("%d",&n);
    ///要申请的进程数大于当前系统的内存
    if(n>100){
        printf("当前内存已满");
        return 0;
    }
    int i,j;
    long id;
    T t;
        for(i=1;i<=n;i++){
            ///当就绪队列为空时,第一个进程id可以直接写入
            if(L.front->next==NULL){
                printf("请输入进程id:");
                scanf("%ld",&pcb[i+N].t_id);
                getchar();
                printf("请输入进程名:");
                gets(pcb[i+N].t_name);
                printf("请输入进程运行时间:");
                scanf("%f",&pcb[i+N].t_time);
                getchar();
                printf("请输入进程优先级:");
                scanf("%d",&pcb[i+N].priority);
                N++;///当前进程数加1
            }else{
                printf("请输入进程id:");
                scanf("%ld",&id);
                ///当就绪队列不为空时,需要检查所创建的进程id是否重复
                for(j=1;j<i+N;){
                    if(id==pcb[j].t_id){
                        printf("进程ID已经存在!\n请重新输入:");
                        scanf("%ld",&id);
                        j=0;
                    }else{
                        j++;
                    }
                }
                pcb[i+N].t_id=id;
                getchar();
                printf("请输入进程名:");
                gets(pcb[i+N].t_name);
                printf("请输入进程运行时间:");
                scanf("%f",&pcb[i+N].t_time);
                getchar();
                printf("请输入进程优先级:");
                scanf("%d",&pcb[i+N].priority);
                N++;///当前进程数加1
            }
            ///将当前进程加入就绪队列
            t=malloc(sizeof(T));
            t->data=N;
            t->next=NULL;
            ///将就绪队列中的进程加入消息缓冲队列
            L.rear->next=t;
            L.rear=t;
        }
    Sort();
    return 0;
}
void Sort(){
    int i,j;
     ///将进程按优先级排序
    for(i=1;i<=N;i++){
        for(j=i+1;j<=N;j++){
            if(pcb[i].priority<pcb[j].priority){
                PCB temp=pcb[i];
                pcb[i]=pcb[j];
                pcb[j]=temp;
            }
        }

    }
}
///显示已经就绪的进程
void display(){
    T p;
    p=L.front;
    if(p->next==NULL){
        printf("当前无进程!");
    }
    while(p->next!=NULL){
        p=p->next;
        printf(" 进程ID:%ld\n 进程名:%s \n运行时间:%f \n优先级:%d\n",pcb[p->data].t_id,pcb[p->data].t_name,pcb[p->data].t_time,pcb[p->data].priority);
    }
}
///进程终止
void kill(){
    int id;
    T p;
    p=L.front;
    if(p->next==NULL){
        printf("当前无进程!\n\n");
    }else{
        printf("输入要终止的进程的id:");
        scanf("%ld",&id);
        while(pcb[p->next->data].t_id!=id){
            if(p->next==NULL){
                printf("该进程不存在!\n");
                return 0;
            }
            p=p->next;
        }
        if(pcb[p->next->data].t_id==id){
            p->next=p->next->next;
            /*当L.front->next==NULL时,
            说明当前杀死的进程是系统中最后一个进程,
            此时首位指针指向同一个位置*/
            if(L.front->next==NULL){
                L.front=L.rear;
            }
            /*当p->next==NULL时,
            说明当前杀死的进程是队尾进程,
            此时尾指针指向p*/
            if(p->next==NULL){
                L.rear=p;
            }
            ///删除已终止进程的PCB进程控制块信息
            while(p->next!=NULL){
                p->next->data--;
                pcb[p->next->data]=pcb[p->next->data+1];
                p=p->next;
            }
        }
    printf("成功杀死进程!\n");
    return 0;
    }
}
void menu(){
    int n;
    while(1){
        printf("\n*************进程演示系统*************\n");
        printf("             1.创建进程\n");
        printf("             2.查看进程\n");
        printf("             3.杀死进程\n");
        printf("             4.退出程序\n");
        printf("***************************************\n\n");
        printf("请输入你的选择(1-4):");
        scanf("%d",&n);
        switch(n){
            case 1:Create();
            break;
            case 2:display();
            break;
            case 3:kill();
            break;
            case 4:return 0;
            default:printf("没有这个选项!");
            break;
        }
    }
    return 0;
}
int main()
{
    InitQueue();
    menu();
    return 0;
}

运行截图:
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯狂的小强呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值