进程通信的模拟实现

总体设计

数据结构定义:

  • 结构体PCB:进程ID、优先级等,增加了消息队列指针
  • 结构体消息块:消息发送者,消息内容,指向下一条消息的指针
  • 就绪队列:已就绪的进程id,指向下一个进程的指针
  • 结构体PCB数组:模拟当前内存大小

函数

Init()——初始化就绪队列;
Create()——进程创建;
isOrNot(int num)——判断进程是否已经创建;
call(Ready r)——调用进程;
kill(Ready r)——进程撤销;
display(Ready r)——就绪队列输出函数:
send()——用于两个进程之间发送消息;
receive()——用于进程接收消息;
showMessage()——消息进程的消息队列;
menu(Ready r)——功能选择界面;

功能测试:

编程实现基于消息缓冲队列机制的进程通信数据结构(创建消息、发送消息、接收消息),在菜单中选择执行各功能,从显示出的就绪队列状态和消息队列状态,查看操作的正确与否。

详细设计

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

在Init()中,我主要创建了进程的头结点,方便后面进程的调用和撤销。
在Create()函数中,我主要将要创建的进程的参数填入PCB,并插入到就绪队列中。在Create()函数中我首先进行了一次判断,判断n是否大于100,如果n>100,说明PCB数组已满(即模拟内存已满)就不能再继续创建进程了,反之可以;然后输入要创建的进程id,并根据已定义的一个函数来判断当前id是否已被创建;如果id重复,我们就要重新输入,直至成功为止,然后将填入参数的PCB节点中,即进程创建成功。
isOrNot(int num)主要是判断当前进程的id是否已经存在,在进程输入的时候会多次调用进行判断。
call(Ready r)主要是调用进程,输入要调用的进程的id,将进程插入到就绪队列中。
kill(Ready r)主要是撤销进程,输入要撤销的进程的id,将进程从就绪队列中移出。
display()函数主要是输出当前就绪队列中的所有就绪队列的信息,我们可以借助这个函数来查看我们对进程的每一次操作是否成功。
send()主要用于进程之间发送消息,首先要输入发送端和接收端的id,输入要发送的消息,将发送端发送的消息插入到接收端的消息队列中,即发送成功。
receive()用于接收端接收消息,首先输入要接收消息的进程id,将消息从其缓冲队列中移出,即消息接收成功。
showMessage()主要作用是查看消息队列,方便我们判断每一次的消息发送和接收是否成功。
menu()是菜单函数,让我们进行功能选择,我们可以从菜单中选择调用上述的任一函数,从而进一步对进程的创建与撤销进行操作。

代码实现:

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

///消息块控制结构
typedef struct MessageNode *Message;
struct MessageNode{
    int sender;///发送者
    char info[100];///消息内容
    Message next;///指向下一条消息的指针
};

///PCB控制块信息
typedef struct PCBnode{
    int id;///进程id
    int priority;///进程优先级
    int status;///进程状态 0:未就绪 1:运行
    Message front;///消息队列头指针
}PCB;

///就绪队列
typedef struct ReadyNode *Ready;
struct ReadyNode{
    Ready next;///指向下一个进程
    int data;///已就绪的进程id
};

PCB pcb[100];///结构体PCB数组,模拟当前内存大小
int N=0;///当前已经创建的进程数目

///创建进程:申请PCB,填入进程参数
void Create(){
    int num;
    ///要申请的进程数大于当前系统的内存
    if(N>100){
        printf("当前内存已满!\n");
        return 0;
    }
    printf("输入要创建的进程的id:");
    scanf("%d",&num);
    getchar();
    while(isOrNot(num)==1){
        printf("请重新输入:");
        scanf("%d",&num);
        getchar();
    }
    pcb[N].id=num;
    printf("输入要创建的进程的优先级:");
    scanf("%d",&pcb[N].priority);
    getchar();
    pcb[N].status=0;
    pcb[N].front=(Message)malloc(sizeof(struct MessageNode));
    pcb[N].front->next=NULL;
    N++;
    return 0;
}

///判断进程是否已创建
int isOrNot(int num){
    for(int i=0;i<N;i++){
        if(num==pcb[i].id){
            printf("该进程已创建!\n");
            return 1;
        }
    }
    return 0;
}

///初始化就绪队列
Ready init(){
    Ready head;
    head=(Ready)malloc(sizeof(struct ReadyNode));
    head->next=NULL;
    return head;
}

///调用进程
void call(Ready r){
    int num;
    Ready p;
    printf("请输入要调用的进程的id:");
    scanf("%d",&num);
    if(r==NULL){
        printf("当前无可调用进程!\n");
        return 0;
    }
    for(int i=0;i<N;i++){
        if(num==pcb[i].id){
            pcb[i].status=1;
            p=(Ready)malloc(sizeof(struct ReadyNode));
            p->data=pcb[i].id;
            p->next=r->next;
            r->next=p;
            printf("调用成功!\n");
            return 0;
        }
    }
    printf("内存中无该进程!\n");
    return 0;

}

///显示正在被调用的进程
void display(Ready r){
    Ready p=r->next;
    if(p==NULL){
        printf("当前无正在运行的进程!\n");
        return 0;
    }
    while(p!=NULL){
        printf("当前正在运行的进程:%d\n",p->data);
        p=p->next;
    }
    return 0;
}


///撤销进程
void kill(Ready r){
    int num;
    Ready temp,p=r;
    if(p->next==NULL){
        printf("当前系统中无可运行的进程!\n");
        return 0;
    }
    printf("请输入要撤销的进程的id:");
    scanf("%d",&num);
    while(p->next!=NULL){
        if(p->next->data==num){
            for(int i=0;i<N;i++){
                if(pcb[i].id==num){
                    pcb[i].status=0;
                }
            }
            temp=p->next;
            p->next=p->next->next;
            free(temp);
            printf("撤销成功!\n");
            return 0;
        }
        p=p->next;
    }
    printf("内存中无该进程!\n");
}

///发送消息
void send(){
    int send_id,receiver_id;
    Message M,h;
    printf("请输入消息发送方的id:");
    scanf("%d",&send_id);
    getchar();
    printf("请输入消息接收方的id:");
    scanf("%d",&receiver_id);
    getchar();
    for(int i=0;i<N;i++){
        if(receiver_id==pcb[i].id){
            M=(Message)malloc(sizeof(struct MessageNode));
            M->sender=send_id;
            printf("请输入消息内容:");
            gets(M->info);
            M->next=pcb[i].front->next;
            pcb[i].front->next=M;
            printf("发送成功!\n");
            return 0;
        }
    }
    printf("发送失败!\n");

}
///接收消息
void receive(){
    int num;
    Message m;
    printf("请输入消息接收方的id:");
    scanf("%d",&num);
    for(int i=0;i<N;i++){
        if(pcb[i].id==num){
            if(pcb[i].front->next==NULL){
                printf("消息队列为空!\n");
            }else{
                m=pcb[i].front->next;
                pcb[i].front->next=pcb[i].front->next->next;
                free(m);
                printf("接收成功!\n");
            }
            return 0;
        }
    }

    return 0;
}

///显示消息
void showMessage(){
    int num;
    Message m;
    printf("请输入要显示消息队列的进程id:");
    scanf("%d",&num);
    for(int i=0;i<N;i++){
        if(num==pcb[i].id){
            m=pcb[i].front->next;
            if(m==NULL){
                printf("消息队列为空!\n");
                return 0;
            }
            while(m!=NULL){
                printf("%d: %s\n",m->sender,m->info);
                m=m->next;
            }
            return 0;
        }
    }
    printf("该进程不存在!\n");
    return 0;
}

void menu(Ready r){
    int n;
    while(1){
        printf("\n***********进程演示系统*************\n");
        printf("       1.创建进程  2.调用进程\n");
        printf("       3.发送消息  4.接收消息\n");
        printf("       5.查看进程  6.撤销进程\n");
        printf("       7.显示消息  8.退出程序\n");
        printf("************************************\n\n");
        printf("请输入你的选择(1-8):");
        scanf("%d",&n);
        switch(n){
            case 1:Create();
            break;
            case 2:call(r);
            break;
            case 3:send();
            break;
            case 4:receive();
            break;
            case 5:display(r);
            break;
            case 6:kill(r);
            break;
            case 7:showMessage();
                break;
            case 8:return 0;
            default:printf("没有这个选项!");
            break;
        }
    }
    return 0;
}
int main()
{
    Ready r;
    r=init();
    menu(r);
    return 0;
}
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;
}

运行截图:
进程创建:
在这里插入图片描述
进程调用:
在这里插入图片描述
进程通信:
在这里插入图片描述

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯狂的小强呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值