进程替换(理解Xshell的基本原理)

替换原理

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

int main()
{
	printf("我是一个进程,我的pid=%d\n", getpid());
	execl("/usr/bin/ls", "ls", NULL);
	printf("我是一个进程,我的pid=%d\n", getpid());
	return 0;
}

例如在这样的一个进程替换中,最后一行的printf不会执行

在这里插入图片描述

使用进程替换函数

以下几个为常用的进程替换函数

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

在这里插入图片描述
execl

int main()
{
 printf("我是一个进程,我的pid=%d\n",getpid());
 execl("/usr/bin/ls","ls","-l",NULL);                                                                                                                                                                     
 
 return 0;
 }

在这里插入图片描述
execv

int main()
{
	printf("我是一个进程,我的pid=%d\n", getpid());
	char* const argy[] = { (char*)"ls",(char*)"-l",NULL };
	execv("/usr/bin/ls",argy);
	return 0;
}

在这里插入图片描述
execlp

int main()
{
	printf("我是一个进程,我的pid=%d\n", getpid());
	execlp("ls","ls", "-l",NULL);
	return 0;
}

在这里插入图片描述
execvp

int main()
{
	printf("我是一个进程,我的pid=%d\n", getpid());
	char* const argy[] = { (char*)"ls",(char*)"-l",NULL };
	execvp("ls", argy);
	return 0;
}

在这里插入图片描述

Xshell的基本原理

Xshell在执行我们的命令时,会将我们的命令进行解析,在创建一个子进程(fork),再进行子进程的替换(execvp),父进程等待子进程的退出(wait)

简易Xshell

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>

#define Max_Num 1024
#define Max_Size 128


char line_command[Max_Num] = "\0";
char* command_args[Max_Size];


int main()
{
    while (1)
    {
        //打印提示符
        printf("[zjq@主机 当前目录#]");
        fflush(stdout);
        //获取用户输入
        //
        memset(line_command, 0, Max_Num * sizeof(char));
        fgets(line_command, Max_Num, stdin);

        line_command[strlen(line_command) - 1] = 0;

        printf("%s", line_command);
        fflush(stdout);
        int index = 0;

        command_args[index++] = strtok(line_command, " ");
        while (command_args[index++] = strtok(NULL, " "));

        //创建新进程
        pid_t id = fork();
        //子进程
        if (id == 0)
        {
            execvp(command_args[0], command_args);
        }
        else
        {
            int ret = waitpid(id, NULL, 0);
            printf("等待成功\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值