zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155320 第五周 加分题-mybash的实现

    2017-2018-1 20155320 第五周 加分题-mybash的实现

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

    学习函数的使用

    使用man命令来查找函数的使用

    • fork函数

    fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源.

    父进程从fork返回处继续执行,在父进程中,fork返回子进程PID
    子进程从fork返回处开始执行,在子进程中,fork返回0

    • 其实对fork函数中子进程与父进程的调用感觉有点绕,然后又学习了一下娄老师提供的几个demo代码,运行结果如下:

      n个fork,2^n个after

      fork()返回中1代表父进程,0代表子进程

    • exec函数

    fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法

    • wait函数

    常用来阻塞进程,当父进程的所有子进程都还在运行,调用wait将使父进程阻塞。

    mybash的实现

    • 根据娄老师上课所讲的思路,就是在父进程中用while循环来根据命令调用命令的实现1.命令以字符串的形式输入 2. pid用来区分进程

    伪代码

    while(1){
        输入命令
        创建子进程
        执行命令
        等待命令执行结束
    }
    

    产品代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>
    #define len 100
    #define MAX 100
    typedef int pid_t;
    
    char* make(char *buf)//将字符串传入参数表内
    {
        char *cp;
        cp=malloc(strlen(buf)+1);
        if (cp==NULL)
        {
            fprintf(stderr,"no memory
    ");
            exit(1);
        }
        strcpy(cp,buf);
        return cp;
    }
    
    int change(char *buf,char *arglist[])//对于字符串进行分割
    {
       int num,j,i,last;
        char buffer[len];
        num=0;
        i=0;
        while (num<MAX)
        {
            if (buf[i]=='
    ')
            {
                arglist[num]=NULL;
                  return num;
               
            }
            if (buf[i]==' ') i++;
            last=i;
            while (buf[i]!=' ' && buf[i]!='
    ') i++;
            for (j=last;j<i;j++) buffer[j-last]=buf[j];
            buffer[j-last]='';
            arglist[num++]=make(buffer);
        }
        
    }
    
    int main(){
     pid_t pid;
     char *arglist[MAX];//shell指令参数表
     char buf[len];
     int x;
     while(1){
     printf("mybash~:");
      fflush(stdout);
     fgets(buf,len,stdin);//读入单行指令
    x=change(buf,arglist);
    /*for(x=0;x<strlen(buf)-1;x++){
      *arglist[x]=buf[0];
    }*/
     pid=fork();//创建一个子进程
     if(pid<0) /* 如果出错 */
                   printf("error ocurred!/n");
     if(pid==0){
       execvp(arglist[0],arglist);//执行命令
       }
      waitpid(pid,NULL,0);//等待子进程结束
     }
     return 0;
    }
    
    
    
    • 实现结果

    实现中出现的问题

    • 问题1:第一次运行时,不知道为啥命令运行不了

    • 解决1:看了几个同学的博客,说加一个/bin,但我尝试了一下仍然无法运行。出现了如下图所示情况

    • 解决2:通过仔细查看之前出现的警告,我发现我犯了个愚蠢的错误,execvp函数中需要指针传参。

    • 解决3:我尝试将buf的值赋给指针数组arglist,结果出现段错误

    • 解决4:通过网上查询,在linux下shell的简单实现,研究了一下别人的代码,给我一些启发,发现重新修改了一下buf和arglist的转换,终于正确了

  • 相关阅读:
    ACM-ICPC 2017 西安赛区现场赛 A. XOR(线性基+线段树)
    ACM-ICPC 2017 西安赛区现场赛 K. LOVER II && LibreOJ#6062. 「2017 山东一轮集训 Day2」Pair(线段树)
    Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences(DP)
    URAL 2052 Physical Education(数位DP)
    Educational Codeforces Round 50 (Rated for Div. 2) F
    Codeforces Round #509 (Div. 2) F. Ray in the tube(思维)
    Codeforces Round #509 (Div. 2) E. Tree Reconstruction(构造)
    ACM-ICPC 2018 青岛赛区网络预赛 J. Press the Button(数学)
    ACM-ICPC 2018 焦作赛区网络预赛 K. Transport Ship(DP)
    [ Codeforces Round #549 (Div. 2)][D. The Beatles][exgcd]
  • 原文地址:https://www.cnblogs.com/ljq1997/p/8010947.html
Copyright © 2011-2022 走看看