• 2017-2018-1 20155215 第五周 mybash的实现


    题目要求

    • 使用fork,exec,wait实现mybash
    • 写出伪代码,产品代码和测试代码
    • 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)

    学习fork,exec,wait

    fork

    • man fork

    fork 这个英文单词在英文里是"分叉"意思, fork() 这个函数作用也很符合这个意思. 它的作用是复制当前进程(包括进程在内存里的堆栈数据)为1个新的镜像. 然后这个新的镜像和旧的进程同时执行下去. 相当于本来1个进程, 遇到fork() 函数后就分叉成两个进程同时执行了. 而且这两个进程是互不影响

    exec

    • man exec

    虽然使用if 对 fork() 的返回值进行判断, 实现了子进程和 主进程在if判断的范围内执行了不同的代码, 但是一旦if执行完成, 他们还是会各自执行后面的代码.
    通常这不是我们期望的, 我们更多时会希望子进程执行一段特别的代码后就让他结束, 后面的代码让主程序执行就行了.
    这个实现起来很简单, 在子程序的if 条件内最后加上exit() 函数就ok了.

    wait

    • man wait

    主程序和子程序的执行次序是随机的, 但是实际情况下, 通常我们希望子进程执行后, 才继续执行主进程.
    例如对于上面的fork_1()函数, 我想先输出子进程的8个 "This is child process" 然后再输出 8个 主进程"This is parent process", 改如何做?
    wait()函数就提供了这个功能, 在if 条件内的 主进程呢部分内 加上wait() 函数, 就可以让主进程执行fork()函数时先hold 住, 等子进程退出后再执行, 通常会配合子进程的exit()函数一同使用.

    写出伪代码,产品代码和测试代码

    • 产品代码如下:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>
    
    #define	MAX 10	
    #define	EXIT_FLAG "quit"
    #define	CMD_BUFFER_SIZE	256	//命令缓冲区大小
    
    int main(void)
    {
         char * argv[MAX];
         char cmdBuffer[CMD_BUFFER_SIZE];
         int pid;
         int status;
         int paraNum;	//参数个数
    
         while(1)	
         {
              printf("mybash >");
              fflush(stdout);	//及时输出命令提示符
              fgets(cmdBuffer, CMD_BUFFER_SIZE, stdin);
              if(cmdBuffer[0] == '
    ')
              {
                   continue;
              }
              if(cmdBuffer[strlen(cmdBuffer)-1] == '
    ')
                   {//去掉末尾回车符
                          cmdBuffer[strlen(cmdBuffer)-1] = 0;
                    }
              if(!strcmp(cmdBuffer, EXIT_FLAG))
              {
                        break;
              }
    
              //分割参数
              paraNum = 1;
              argv[0] = strtok(cmdBuffer, " ");	//空格进行分割
              while( (paraNum < MAX) &&(argv[paraNum] = strtok(NULL, " ")) )
                   {
                        paraNum++;
                   }
             //创建子进程以执行命令
              pid = vfork();
              if( pid == 0 )
              {//子进程执行命令
                    execvp(argv[0], argv);
                    perror("execvp");
                    exit(EXIT_FAILURE);
              }else if( pid < 0 )
                   {//错误
                        perror("vfork");
                        exit(EXIT_FAILURE);
                        }else
                           {
                                  waitpid(pid, &status, 0);	//等待子进程结束
                                  }
                        }
              return 0;
    }
    
  • 相关阅读:
    链表和顺序表的区别
    MongoDB安装了以后,服务无法启动的问题
    retrying模块
    Scrapy 动态创建 Item
    pyhon把程序打包为whl
    记录有个关于使用matplotlib库绘图遇到的坑
    读取Polygon多边形的顶点坐标
    Scatter 散点图
    tick 能见度
    Annotation 标注
  • 原文地址:https://www.cnblogs.com/xuanyan/p/8018896.html
Copyright © 2020-2023  润新知