第二次上机实验mysys.c

文章介绍了如何实现一个名为mysys的函数,该函数类似于系统函数system,但要求使用fork、exec和wait系统调用来执行命令,而不依赖于system或shell。主要涉及进程创建、命令解析(使用strtok)和execvp调用。在实现中,作者遇到了只执行第一个命令的问题,并通过调整fork后的处理解决了这个问题。
摘要由CSDN通过智能技术生成

  作业 mysys.c

  实现函数mysys,用于执行一个系统命令

  mysys的功能与系统函数system相同,要求用进程管理相关系统调用自己实现一遍

  参考 API system,了解 system 的功能

  你的实现要使用fork/exec/wait系统调用,3个都要用到

  不能调用系统函数 system 的功能

  不能调用系统程序 sh 的功能

  测试程序

#include <stdio.h>

void mysys(char *command)
{
    实现该函数,该函数执行一条命令,并等待该命令执行结束
}

int main()
{
    printf("--------------------------------------------------\n");
    mysys("echo HELLO WORLD");
    printf("--------------------------------------------------\n");
    mysys("ls /");
    printf("--------------------------------------------------\n");
    return 0;
}

  测试程序的输出结果

--------------------------------------------------
HELLO WORLD
--------------------------------------------------
bin    core  home	     lib	 mnt   root  snap  tmp	vmlinuz
boot   dev   initrd.img      lost+found  opt   run   srv   usr	vmlinuz.old
cdrom  etc   initrd.img.old  media	 proc  sbin  sys   var
--------------------------------------------------

个人思路

1.题目意思就是不调用system和sh,用fork\exec\wait实现system的功能。

2.echo,ls等用exec的系统调用功能可以实现,那到底是用execvp还是execlp呢?我使用的execvp。

execlp解释如下:

execlp和execl的区别一句话就是能否用path环境变量。

execvp原型如下:

execvp和execlp区别就是一个是使用数组,一个是使用list。注意execl、execlp、execv、execvp区别。

 3.理解进程的并发和隔离特性:

a.并发特性

父进程和子进程并发运行

父进程创建子进程后,父子进程都处于运行状态中

两个进程的输出结果是交织在一起的

两者的代码段内容相同

父进程从fork()返回处执行,fork()返回为子进程的PID

子进程从fork()返回处执行,fork()返回0

 b.隔离特性

进程的地址空间是互相隔离的

每个进程拥有自己的地址空间

进程仅能访问自己的地址空间

如果出现非法内存访问,仅仅当前进程受到影响

全局变量

全局变量存在于两个地址空间中,并非被两个进程共享

父进程和子进程访问的是自己的全局变量,互相不影响

 4.分词用strtok,结构体等之前第一次作业中讲过。

其余的直接上源码看注释:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<sys/wait.h>
struct Command{
    int agrc;
    char *agrv[16];
}commands;
void parse_command(char *command)
{        //分词函数
    char *line=(char*)malloc(sizeof(command));
    strcpy(line,command);
    commands.agrc=0;
    for(int i=0;i<16;i++)
    {
        commands.agrv[i]=NULL;
    }

    char *word;
    
    word=strtok(line," ");
    while(word!=NULL)
    {
        commands.agrv[commands.agrc++]=word;
        word=strtok(NULL," ");
    }

}    
void mysys(char *command)
{
    pid_t pid;
    parse_command(command);

    pid=fork();        //创建线程
    if(pid==0)        //子线程时
    execvp(commands.agrv[0],commands.agrv);        //这里要用execvp
    wait(NULL);
    
}    
int main()
{
    printf("---------------------------------------------------\n");
    mysys("echo HELLO WORLD a b c");
    printf("---------------------------------------------------\n");
    mysys("ls /");
    printf("---------------------------------------------------\n");
    return 0;
}

 之前的代码是用if对fork进行判断,又是if(pid==0) 子线程 else 父线程 ,运行的时候会出现只执行第一个mysys,debug了很久不知道是什么问题,后面把对创建线程是否创建成功去掉,把else 父进程也去掉,确保了wait一定能执行。

个人思路,仅供参考,如有不足,多多指正,喜欢或者是有帮助麻烦帮忙点赞、收藏,感谢阅读!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值