linux学习(进程替换)[10]

创建子进程

fork()创建子进程进行替换,不影响父进程,父进程聚焦在:读取数据、解析数据、指派进程、执行代码的功能。
linux学习(进程替换)[10]_第1张图片

子进程发生替换后的数据

在加载新程序进去之前,父子之间的的代码是共享的,数据写时拷贝进子进程。
当加载新程序后,也是一种写入。代码要不要拷贝呢?
重新加载后,父子的代码必须分离
在这里插入图片描述

exe系列

linux学习(进程替换)[10]_第2张图片
linux学习(进程替换)[10]_第3张图片
在这里插入图片描述
execlp会自己在PATH环境中查找,不用告知程序的路径
在这里插入图片描述
linux学习(进程替换)[10]_第4张图片
在这里插入图片描述

linux学习(进程替换)[10]_第5张图片

执行自己的程序

linux学习(进程替换)[10]_第6张图片
在这里插入图片描述
下面是一个示例,展示了如何在Linux下使用exec系列命令创建子进程并运行自己写的代码,同时父进程继续执行其他任务:

#include 
#include 
#include 
#include 

int main() {
    pid_t pid = fork(); // 创建子进程

    if (pid == -1) {
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // 子进程中执行自己的代码
        printf("Child process: Hello, I am the child process!\n");
        // 使用exec系列命令运行自己的代码
        execl("/path/to/your/executable", "/path/to/your/executable", NULL);
        // 如果exec执行失败,则会继续执行以下代码
        perror("execl");
        return 1;
    } else {
        // 父进程继续执行其他任务
        printf("Parent process: Hello, I am the parent process!\n");
        // 等待子进程结束
        wait(NULL);
        printf("Parent process: Child process has finished.\n");
    }

    return 0;
}

在上面的示例中,首先使用fork函数创建了一个子进程。子进程通过判断fork的返回值来确定自己是子进程还是父进程。如果返回值为0,则表示是子进程,子进程中执行了自己的代码,并使用execl命令运行自己的可执行文件。如果execl执行成功,则子进程的代码会被替换为新的代码,否则会打印错误信息。父进程则继续执行其他任务,并使用wait函数等待子进程结束。

请注意,上述示例中的/path/to/your/executable需要替换为自己的可执行文件的路径。此外,还需要将自己的代码编译为可执行文件,并确保具有执行权限。

给子进程传递环境变量

要在上述代码的基础上给子进程传递环境变量,可以使用execle函数而不是execl函数。execle函数允许您指定要传递给子进程的环境变量。

下面是修改后的示例代码:

#include 
#include 
#include 
#include 

int main() {
    pid_t pid = fork(); // 创建子进程

    if (pid == -1) {
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // 子进程中执行自己的代码
        printf("Child process: Hello, I am the child process!\n");
        // 创建环境变量数组
        char* envp[] = {
            "VAR1=value1",
            "VAR2=value2",
            NULL
        };
        // 使用execle命令运行自己的代码,并传递环境变量
        execle("/path/to/your/executable", "/path/to/your/executable", NULL, envp);
        // 如果execle执行失败,则会继续执行以下代码
        perror("execle");
        return 1;
    } else {
        // 父进程继续执行其他任务
        printf("Parent process: Hello, I am the parent process!\n");
        // 等待子进程结束
        wait(NULL);
        printf("Parent process: Child process has finished.\n");
    }

    return 0;
}

在上述示例中,我们创建了一个envp数组,其中包含要传递给子进程的环境变量。数组的最后一个元素必须为NULL,以表示环境变量列表的结束。

然后,我们使用execle函数来运行自己的可执行文件,并将环境变量数组作为参数传递给它。execle函数的最后一个参数是一个指向环境变量数组的指针。

请确保将/path/to/your/executable替换为自己的可执行文件的路径,并根据需要修改环境变量数组。

linux学习(进程替换)[10]_第7张图片
linux学习(进程替换)[10]_第8张图片
linux学习(进程替换)[10]_第9张图片

myproc.c

#include 
#include 
#include 
#include 

int main()
{
    extern char **environ;
    pid_t id = fork();
    if(id == 0)
    {
        //child
        printf("我是子进程: %d\n", getpid());
        //execl: 如果替换成功,不会有返回值,如果替换失败,一定有返回值 ==》如果失败了,必定返回 ==》 只要有返回值,就失败了
        //不用对该函数进行返回值判断,只要继续向后运行一定是失败的!
        //execl("/bin/ls", "ls", "-a", "-ln", NULL); //lsssss: 不存在
        //char *const myargv[] = {
        //    "ls",
        //    "-a",
        //    "-l",
        //    "-n",
        //    NULL
        //};
        //execv("/bin/ls", myargv); //lsssss: 不存在
        //execlp("ls", "ls", "-a", "-l", "-n", NULL);
        //execvp("ls", myargv);
        //char *const myenv[] = {
        //    "MYENV=YouCanSeeMe",
        //    NULL
        //};
        //putenv("MYENV=YouCanSeeMe");
        //execle("./exec/otherproc", "otherproc", NULL, environ);
        //execl("./exec/shell.sh", "shell.sh", NULL);
        execl("./exec/test.py", "test.py", NULL);
        exit(1);
    }

    sleep(1);
    //father
    int status = 0;
    printf("我是父进程: %d\n", getpid());
    waitpid(id, &status, 0);
    printf("child exit code: %d\n", WEXITSTATUS(status));

    return 0;
}

你可能感兴趣的:(linux,linux,学习)