在win下使用C模拟fork()以及进程间通信

这篇博客展示了作者在大三上学期操作系统的实验,实现了进程创建、查看、换出、杀死、唤醒以及fork和进程通信的模拟。通过一个简单的内存模型,模拟了进程的fork行为,包括复制父进程的状态并更新父子标志。此外,还模拟了管道通信,涉及权限管理和信息传递。尽管代码简单,但涵盖了基本的进程控制和通信原理。

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

前言

这是大三上学期的操作系统的实验,过程感触比较深,但是同时又感觉自己学的很浅薄,所以就将这个自己理解的过程与源码发上来。做为笔记以及方便以后再做查看。如果有实验需求的也可以跑一下这个程序和你所理解的fork()以及进程通信有什么区别。

分块解释

1.fork()实现(部分)

  • 代码如下
void winfork()//fork函数模拟--行为模式:子进程就返回0,非子进程返回该进程的子进程的pid
{
   
    /**********************判断结构***************/
    if(num==0)
    {
   
        printf("当前没有运行的进程,无法进行fork()行为\n");
        return;
    }
    if (num==20)
    {
   
        printf("fork error!");
        return;//内存没空间创建子进程
    }
    /*******************************************/
    /**********模拟复制内容部分*********/

    printf("\n请输入要执行fork()的进程的pid值:\n");    //选择父进程
    scanf("%d",&pid);                                           //此时的pid是父进程的pid
    sign=0;
    for(i=0;i<20;i++)
        {
   
        if(RAM[i].pid==pid)                                  //在20个内存里查找pid符合条件的父进程
            {
   
            if(RAM[i].child_sign==0)                                     //pid符合条件且其下没有子进程
                {
   
                printf("\n请输入子进程的pid\n");          //对新建的子进程的pid赋值
                scanf("%d",&RAM[num+1].pid);
                for(j=0;j<num;j++) /*判断是否之前已存储相同pid进程*/
                if(RAM[j].pid==RAM[num+1].pid)
                    {
   
                    printf("\n该进程pid已存在于内存中");
                    return;
                    }
                RAM[num+1].priority=RAM[i].priority;
                RAM[num+1].size=RAM[i].size;
                strcpy(RAM[num+1].task,RAM[i].task);
                RAM[num+1].state=1; /*将进程状态设为1,表示在内存中*/
                RAM[num+1].child_sign=0;
                RAM[i].child_sign=RAM[num+1].pid;
                if(RAM[i].fds_0!=2){
   //权限同步
                    RAM[num+1].fds_0=RAM[i].fds_0;
                    RAM[num+1].fds_1=RAM[i].fds_1;
                }
                num++;/*内存中进程数目加一*/
                sign=1;
                return;
                }
            }
        }
        if(sign==0) printf("\n执行失败!\n" );
}

我做的只是一个完成度很低的模拟(能力不足),这里我主要是模拟了fork会使得子进程基础父进程所有状态(除进程标识符和父子标志外)相同,并且对于父子进程标志会有更改。

RAM[num+1].child_sign=0;
RAM[i].child_sign=RAM[num+1].pid;

以及权限同步

RAM[num+1].fds_0=RAM[i].fds_0;
RAM[num+1].fds_1=RAM[i].fds_1;

2.进程通信模拟(部分)

以下流程有关于函数实现pipe建立管道后建立子进程,并关闭父进程的
管道本质为内核缓冲区,用户态来看是一个伪文件
由于是伪文件,所以对于管道有两个文件描述符引用,一个表示读端,一个表示写端
管道是基于字节流实现通信的
管道依赖于文件系统,其生命周期随进程
管道本身自带同步互斥
fork()进程的时候,子进程会继承父进程的管道与其描述符
单方向流动,半双工通信类型,且只作用于有血缘关系的进程之间
代码如下:

void communication()
{
   
     if(num==0)
    {
   
        printf("当前没有运行的进程,无法进行进程通信行为\n");
        return;
    }
    int f_pid,c_pid;//进行进程通信的进程的id(父子)
    char buf[20];//缓存区
    printf("\n 请输入父进程 pid\n");
    scanf("%d",&f_pid);//获取父进程pid

    /************对父进程的确认**********/
     for(i=0;i<20;i++)
        {
   
        if(RAM[i].pid==f_pid)                                  //在20个内存里查找pid符合条件的父进程
            {
   
            if(RAM[i].child_sign==0)                                     //pid符合条件且其下没有子进程建立管道
                {
   
                    if (num==20)return;//无进程空间建立子进程//
                    RAM[i].fds_0=1;     //激活读取权限
                    printf("进程(pid=%d)的读取权限已授权,",RAM[i].pid);
                    RAM[i].fds_1=1;     //激活写入权限
                    printf("进程(pid=%d)的写入权限已授权\n",RAM[i].pid);
                    /******为进程建立子进程并激活权限***********/
                    printf("\n请输入子进程的pid\n");          //对新建的子进程的pid赋值
                    scanf("%d",&RAM[num+1].pid);
                    for(j=0;j<num;j++) /*判断是否之前已存储相同pid进程*/
                    if(RAM[j].pid==RAM[num+1].pid)
                        {
   
                        printf("\n该pid已被占用");
                        return;
                        }
                    RAM[num+1].priority=RAM[i].priority;
                    RAM[num+1].size=RAM[i].size;
                    strcpy(RAM[num+1].task,RAM[i].task);
                    RAM[num+1].state=1; /*将进程状态设为1,表示在内存中*/
                    RAM[num+1].child_sign=0;
                    RAM[i].child_sign=RAM[num+1].pid;
                    if(RAM[i
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小灰不停前进

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

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

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

打赏作者

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

抵扣说明:

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

余额充值