Linux进程控制—02

Linux进程控制—02

1.程序替换

程序替换本质来说就是替换一个pcb在内存中对应的代码和数据。加载另一个程序到内存中,然后更新页表信息,初始化虚拟地址空间。这个进程pcb将从头重新开始调度新的程序运行。

程序替换函数族
int execl(const char* path, const char* arg, ...);
int execlp(const char* flie, 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[]);
int execve(const char* file, char* const argv[], char* const envp[]);
函数的使用

test.c:

#include<stdio.h>
int main(int argc, char* argv[], char* env[])
{
	int i;
	for(i = 0;argc[i] != NULL;i++)
	{
		printf("argv[%d] = %s\n", i, argv[i]);
	}
	for(i = 0;env[i] != NULL;i++)
	{
		printf("env[%d] = %s\n", i, env[i]);
	}
	return 0;
}

主文件:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int argc, char* argv[], char* env[])
{
	execl("./test", "test", "-l", NULL);
    //会去调用当前路径下的test程序,输入参数为test和-l
	char* new_argv[] = {"test", "-L", "-P", NULL};
    execv("./test", new_argv);
    //会去调用当前路径下的test程序,输入参数为该指针数组的内容
	execvp("test", new_argv);
    //如果在PATH环境变量下指定了路径,使用这个函数则可以不用带路径
	char* new_env[] = {"MYVAL=10","TESTVAL=20",NULL};
	execve("./test", new_argv, new_env);
    //会去调用当前路径下的test程序,输入参数为该指针数组内容,同时将设定的环境变量传入。
	return 0;
}

l和v的区别:在于程序运行参数的赋予方式不同,l通过不定参完成/v通过字符串指针数组赋予

有没有p的区别:在于第一个参数执行程序的时候,是否需要带路径,有p则可以不用带路径,默认会去PATH环境变量指定的路径下查找。

有没有e的区别:在于这个进程的环境变量舒服需要程序初始化。有e则表示初始化,没有则表示使用默认的环境变量。通过execve我们能够明白,一个进程的环境变量实际上是他的父进程赋予的。

2.minishell程序

我们在终端中运行一个程序,这个程序的父进程实际上是shell程序。当我们在shell中输入了一个命令,这时候其实shell对这个标准输入进行解析,得到了程序名称,然后创建子进程,并且将子进程的程序替换为当前这个解析出来的程序。

下面我们自己实现一个minishell程序,来体会整个进程控制过程。

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	umask(0);
	while(1)
	{
		printf("[sw@minishell]$ ");
		fflush(stdout);//刷新标准输出缓冲区
        //等待标准输入
		char buf[1024] = {0};
		fgets(buf, 1023, stdin);
		buf[strlen(buf) - 1] = '\0';
        //对标准输入进行解析
		char* ptr = buf;
		char* argv[32] = {NULL};
		int argc = 0;
		while(*ptr != '\0')
		{
			if(*ptr != ' ')
			{
				argv[argc] = ptr;
				argc++;
				while(*ptr !=' ' && *ptr != '\0')
				{
					ptr++;
				}
				*ptr = '\0';
			}
			ptr++;
		}
		argv[argc] = NULL;
        //创建子进程
		pid_t pid = fork();
		if(pid == 0)
		{
            //子进程中进行程序替换
			execvp(argv[0], argv);
			exit(0);
		}
        //父进程进程等待子进程退出
		wait(NULL);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值