[linux] Process waiting, process replacement

Process waiting, process replacement

  • 1. Process waiting
    • 1.1 Necessity of process waiting
    • 1.2 Methods for process waiting
      • 1.2.1wait method
      • 1.2.2waitpid method
      • 1.2.3 Obtain the exit code through macro
      • 1.2.4 Blocking vs. non-blocking
  • 2. Process replacement
    • 2.1 Purpose of process replacement
    • 2.2execl replacement function
    • 2.3 Understand the principles
    • 2.4 Other replacement interfaces
      • 2.4.1execl
      • 2.4.2execlp
      • 2.4.3execv
      • 2.4.4execvp
      • 2.4.5 execute
      • 2.4.6execvp
    • 2.5 Summary

The previous content is about process creation and termination, here it is mainly about process waiting and replacement.

1. Process waiting

1.1 The necessity of process waiting

The process status mentioned before is the zombie process.

1. The child process exits. If the parent process ignores it, it may cause a zombie process, which may cause a memory leak.
2. In addition, the zombie process is already in the exit state. Even if you use kill -9, there is no way to kill a dead process.
3. Finally, we need to know how well the tasks assigned by the parent process to the child process are completed. For example, if the child process is completed, the result is correct or incorrect, or whether it exits normally.

How should we solve the above problems?

The above problem is explained through the process waiting method discussed today.

The parent process uses process waiting to recycle child process resources and obtain child process exit information.

1.2 Process waiting method

1.2.1wait method


The status parameter is discussed below.

On success, returns the id of the process to be waited for. Failure, returns -1;

The following code demonstrates process waiting.

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6
  7 int main()
  8 {<!-- -->
  9 
 10 pid_t id=fork();
 11 if(id == 0)
 12 {<!-- -->
 13 //Subprocess
 14 int cnt=10;
 15 while(cnt)
 16 {<!-- -->
 17 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
 18 sleep(1);
 19}
 20 exit(1);
 twenty one     }                                  
 22 //parent process
 23 sleep(15);
 24 pid_t ret=wait(NULL);
 25 printf("wait success:%d",ret);
 26 sleep(2);
 27 return 0;
 28 }

When the child process exits, it is in the zombie state (Z + ), and then waits until the parent process reclaims the child process resources. The wait parameter here is set to NULL; mainly to demonstrate this process. This parameter will be discussed in detail below.

 while :;do ps ajx | head -1 & amp; & amp; ps ajx | grep 'mytest' | grep -v grep; sleep 1; done // Execute this instruction in a loop

1.2.2waitpid method


The first parameter is the process ID to be waited for, the second parameter is the subprocess exit code, and the third parameter is the waiting mode that temporarily defaults to 0 (blocking waiting).

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6
  7 int main()
  8 {<!-- -->
  9                                            
 10 pid_t id=fork();
 11 if(id == 0)
 12 {<!-- -->
 13 //Subprocess
 14 int cnt=5;
 15 while(cnt)
 16 {<!-- -->
 17 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
 18 sleep(1);
 19}
 20 exit(1);
 twenty one     }                                                                                            
 22 //parent process
 23 sleep(10);
 24 int status=0;
 25 // pid_t ret=wait(NULL);
 26 pid_t ret=waitpid(id, & status,0);
 27 // printf("wait success:%d",ret);
 28 if(ret>0)
 29 {<!-- -->
 30 printf("wait success:%d,ret:%d\
",ret,status);
 31}
 32 sleep(2);
 33 return 0;
 34}


The exit code is 256, and our exit code is 135. This is definitely wrong.

Get child process status

1. Both wait and waitpid have a status parameter, which is an output parameter and is filled in by the operating system.
2. If NULL is passed, it means that the exit status information of the child process is not concerned.
3. Otherwise, the operating system will feedback the exit information of the child process to the parent process based on this parameter.
4. Status cannot simply be treated as an integer, but can be treated as a bitmap. The specific details are as follows (only the lower 16 bits of status are studied):


The next lowest 8 bits are the exit code. Check whether the result is correct after running.
The lower 7 bits indicate whether the process ended normally. If it is 0, it means it ends normally, and the exit code is meaningful at this time. If it is !0 the exit code means nothing.

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6
  7 int main()
  8 {<!-- -->
  9 
 10 pid_t id=fork();
 11 if(id == 0)
 12 {<!-- -->
 13 //Subprocess
 14 int cnt=5;
 15 while(cnt)
 16 {<!-- -->
 17 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
 18 sleep(1);
 19}
 20 exit(1);
 twenty one     }
 22 //parent process
 23 sleep(10);
 24 int status=0;
 25 // pid_t ret=wait(NULL);
 26 pid_t ret=waitpid(id, & status,0);
 27 // printf("wait success:%d",ret);
 28 // printf("wait success:%d,ret:%d\
",ret,status);
 29 if(ret>0)
 30 {<!-- -->
 31 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 32}
 33
 34 sleep(2);
 35 return 0;
 36}


Let’s look at a piece of code where the exit signal is not 0

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6
  7 int main()
  8 {<!-- -->
  9 
 10 pid_t id=fork();
 11 if(id == 0)
 12 {<!-- -->
 13 int *p=NULL;
 14 //Subprocess
 15 int cnt=5;
 16 while(cnt)
 17 {<!-- -->
 18 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
 19 sleep(1);
 20 //Let the child process exit immediately
 21 *p=10;
 twenty two         }
 23 exit(1);
 twenty four     }
 25 //parent process
 26 // sleep(10);
 27 sleep(2);
 28 int status=0;
 29 // pid_t ret=wait(NULL);
 30 pid_t ret=waitpid(id, & status,0);
 31 // printf("wait success:%d",ret);
 32 // printf("wait success:%d,ret:%d\
",ret,status);
 33 if(ret>0)
 34 {<!-- -->
 35 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 36}
 37 sleep(2);
 38 return 0;
 39 }

If the exit signal is not 0, the exit code is meaningless to anyone. 0 is displayed here because our status is passed 0.

kill -l //Check what the exit signal is

So how does the parent process get the exit code of the child process?

Insert image description here

1.2.3 Obtain exit code through macro

Every time you get the exit code, exit signal. When outputting, you need to write it manually. The system provides us with a macro replacement for easy use.

#include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/types.h>
  5 #include<sys/wait.h>
  6
  7 int main()
  8 {<!-- -->
  9 
 10 pid_t id=fork();
 11 if(id == 0)
 12 {<!-- -->
 13 //int *p=NULL;
 14 //Subprocess
 15 int cnt=5;
 16 while(cnt)
 17 {<!-- -->
 18 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
 19 sleep(1);
 20 //Let the child process exit immediately
 21 // *p=10;
 twenty two         }
 23 exit(1);
 twenty four     }
 25 //parent process
 26 // sleep(10);
 27 sleep(2);
 28 int status=0;
 29 // pid_t ret=wait(NULL);
 30 pid_t ret=waitpid(id, & status,0);
 31 if(ret>0)
 32 {<!-- -->
 33 //Determine whether to exit normally
 34 if(WIFEXITED(status))
 35 {<!-- -->
 36 //Determine whether the running result of the child process is correct
 37 printf("exit code:%d\
",WEXITSTATUS(status));
 38 }
 39 else
 40 {<!-- -->
 41 printf("child exit not normal!\
");
 42 }
 43}
 44 return 0;

1.2.4 Blocking vs. non-blocking

We mentioned earlier that the third parameter of waitpid is 0 by default, which is a blocking state.
The following is a short story to help understand blocking and non-blocking.

The final exam is coming soon, and Zhang San wants to ask Li Si’e to refresh his knowledge. So I made an appointment to wait for him downstairs in Li Si’s dormitory. After Zhang San arrived, he called Li Si. Li Si said that he was busy with other things and needed something. Zhang San said it was okay and did not hang up the phone, so he kept waiting for Li Si. Si asked if he was okay. They waited until Li Si was busy before going to study knowledge points together.

Once again, the midterm exam was coming soon, and Zhang San wanted to ask Li Si to help him brush up on his knowledge. Still waiting for Li Si at the same place. Zhang San still called Li Si after arriving this time. Li Si still had something to do and had to wait for a while, but this time Zhang San hung up the phone, and then called Wang Wu and said hello to others. Then he called Li Si again. When Li Si was not well, Zhang San hung up the phone again and went to do other things. After asking Li Si many times, Li Si was busy and went to tutor Zhang San.

1. The first type is that John does not hang up the phone and detects John’s status—-blocking
2. The second type is that Zhang San calls Li Si. If it is not ready, it returns directly —— here is non-blocking waiting every time, multiple non-blocking waits ——-> rounds Inquire.

Call->System call wait/waitpid
Zhang San->parent process
Li Si->Subprocess

Insightful non-blocking

 1 #include<stdio.h>
    2 #include<unistd.h>
    3 #include<stdlib.h>
    4 #include<sys/types.h>
    5 #include<sys/wait.h>
    6
    7 int main()
    8 {<!-- -->
    9 
   10 pid_t id=fork();
   11 if(id == 0)
   12 {<!-- -->
   13 // int *p=NULL;
   14 //Subprocess
   15 int cnt=5;
   16 while(cnt)
   17 {<!-- -->
   18 printf("I am a child process, pid:%d, ppid:%d, cnt = %d\
",getpid(),getppid(),cnt--);
   19 sleep(1);
   20 //Let the child process exit immediately
   21 // *p=10;
   twenty two         }
   23 exit(1);
   twenty four     }

  25 //parent process
 26 // sleep(10);
 27 int status=0;
 28 while(1)//Polling
 29 {<!-- -->
 30 pid_t ret=waitpid(id, & status,WNOHANG);//Non-blocking. The child process does not exit. When the parent process detects it, it returns immediately.
 31 if(ret == 0)
 32 {<!-- --> //waitpid call was successful & amp; & amp; the child process did not exit
 33 printf("wait done,but child is running....\
");
 34}
 35 else if(ret > 0)
 36 {<!-- -->
 37 //waitpid call was successful & amp; & amp; the child process exited
 38 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 39 break;
 40}
 41 else
 42 {<!-- -->
 43 //Call failed
 44 printf("waitpid call failed\
");
 45 break;
 46 }
 47 sleep(1);
 48 }
 49 return 0;

The advantage of non-blocking: it will not take up all the energy of the parent process and can do other things during polling.

2. Process replacement

We used fork to create a child process earlier. What is the purpose of creating a child process?

2.1 The purpose of process replacement

a. Want the child process to execute part of the code of the parent process
Execute part of the disk code corresponding to the parent process

b. Want the child process to execute a brand new program
Let the child process find a way to load the specified program on the disk. Execute the code and data of the new program.

See how to perform process replacement.

2.2execl replacement function

 1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8 
  9 int main()
 10 {<!-- -->
 11 printf("process is running\
");
 12 //All exec series interfaces must end with NULL when passing parameters.
 13 execl("/usr/bin/ls","ls","-l",NULL);
 14 printf("hello\
");
 15
 16 return 0;
 17}

 1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8 
  9 int main()
 10 {<!-- -->
 11 printf("process is running\
");
 12 //All exec series interfaces must end with NULL when passing parameters.
 13 //Add color to executable program
 14 execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
 15 printf("process running done...\
");
 16
 17 return 0;
 18}

See after the pig runs away. Understand the principles of understanding.

2.3 Understand the principles

The essence of program replacement: it is to load the code and data of the specified program into the specified location! Cover your own code and data.

So the process is replaced without creating a new process.

The printf after exexl is not executed because printf is also code and comes after execl. When execl is executed, the code has been completely covered and the code of the new program has started to be executed, so printf cannot be executed.

The execl call failed, that is, the replacement was not successful.

And the exec series has not yet returned a value, because if it succeeds, it has nothing to do with the following code, and the judgment is meaningless. As long as excel returns, it must be an error.

So will child process replacement affect the parent process code?

 1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8 
  9 int main()
 10 {<!-- -->
 11 pid_t id=fork();
 12 assert(id != -1);
 13 if(id == 0)
 14 {<!-- -->
 15 //Subprocess
 16 execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
 17 exit(1);
 18}
 19 //parent process
 20 int status=0;
 21 pid_t ret=waitpid(id, & status,0);
 22 if(ret > 0)
 23 {<!-- -->
 24 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 25}
 26 return 0;


From the above results, we know: The replacement of the child process does not affect the parent process, because the virtual address space + page table ensures process independence. Once there is an execution flow and you want to replace code or data , copy-on-write occurs.

2.4 Other replacement interfaces

2.4.1execl

1int execl(const char *path, const char *arg, …)

l—->list: Pass parameters into execl one by one

2.4.2execlp

int execlp(const char *file, const char *arg, …)

p—->path: Solve how to find the function of the program, the function with p character. You don’t need to tell me the path of the program. You just need to tell me who it is, and I will automatically search for the executable program in the environment variable PATH.

 1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8 
  9 int main()
 10 {<!-- -->
 11 pid_t id=fork();
 12 assert(id != -1);
 13 if(id == 0)
 14 {<!-- -->
 15 //Subprocess
 16 // execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
 17 // There are two ls here, which are actually not repeated. One is to tell the system who I want to execute, and the other is to tell the system how I want to execute it.
 18 execlp("ls","ls","-l","--color=auto",NULL);
 19 exit(1);
 20}
 21 //parent process
 22 int status=0;
 23 pid_t ret=waitpid(id, & status,0);
 24 if(ret > 0)
 25 {<!-- -->
 26 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 27}
 28 return 0;

2.4.3execv

int execv(const char *path, char *const argv[]);

v—–>vector: You can put all execution parameters into an array and pass them uniformly without using the variable parameter scheme.

 1 #include<stdio.h>
    2 #include<assert.h>
    3 #include<stdlib.h>
    4 #include<unistd.h>
    5 #include<sys/types.h>
    6 #include<sys/wait.h>
    7
    8 
    9 int main()
   10 {<!-- -->
   11 pid_t id=fork();
   12 assert(id != -1);
   13 if(id == 0)
   14 {<!-- -->
   15 //Subprocess
   16 // execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
   17 // There are two ls here, which are actually not repeated. One is to tell the system who I want to execute, and the other is to tell the system how I want to execute it.
   18 // execlp("ls","ls","-l","--color=auto",NULL);
   19 char* const argv[]={<!-- -->"ls","-l","--color=auto",NULL};
   20 execv("/usr/bin/ls",argv);
   21 exit(1);
   twenty two     }
   23 //parent process
   24 int status=0;
   25 pid_t ret=waitpid(id, & status,0);
   26 if(ret > 0)
   27 {<!-- -->
   28 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
   29 }
   30 return 0;

2.4.4execvp

int execvp(const char *file, char *const argv[]);

 13 if(id == 0)
   14 {<!-- -->
   15 //Subprocess
   16 // execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
   17 // There are two ls here, which are actually not repeated. One is to tell the system who I want to execute, and the other is to tell the system how I want to execute it.
   18 // execlp("ls","ls","-l","--color=auto",NULL);
 19 char* const argv[]={<!-- -->"ls","-l","--color=auto",NULL};
   20 // execv("/usr/bin/ls",argv);
   21 execvp("ls",argv);
   22 exit(1);
   twenty three     }                                                                            
   24 //parent process
   25 int status=0;
   26 pid_t ret=waitpid(id, & status,0);
   27 if(ret > 0)
   28 {<!-- -->
   29 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
   30}


The above are all for executing system commands, but what if we want to execute a program we wrote ourselves?

 1 #include<stdio.h>
  2                                                                                                                                                                  
  3 //myexe
  4 int main()
  5 {<!-- -->
  6 printf("I am a C program\
");
  7 printf("I am a C program\
");
  8 printf("I am a C program\
");
  9 printf("I am a C program\
");
 10 printf("I am a C program\
");
 11 printf("I am a C program\
");
 12 printf("I am a C program\
");
 13 printf("I am a C program\
");
 14
 15 return 0;
 16}

We know that make scans files from top to bottom by default to form an executable target file. By default, the first one is scanned. What if I want to execute multiple commands at once?

 .PHONY:all
 all: mytest myexe
 
 mytest:test.c
     gcc -o $@ $^ -std=c11
 
 myexe:myexe.c
     gcc -o $@ $^ -std=c11
     
 .PHONY:clean
 clean:
     rm -f mytest myexe

What is modified by PHONY is a pseudo object. This forms two executions at a time.

 1 #include<stdio.h>
    2 #include<assert.h>
    3 #include<stdlib.h>
    4 #include<unistd.h>
    5 #include<sys/types.h>
    6 #include<sys/wait.h>
    7
    8 
    9 int main()
   10 {<!-- -->
   11 pid_t id=fork();
   12 assert(id != -1);
   13 if(id == 0)
   14 {<!-- -->
   15 //Subprocess
   16 // execl("/usr/bin/ls","ls","-l","--color=auto",NULL);
   17 // There are two ls here, which are actually not repeated. One is to tell the system who I want to execute, and the other is to tell the system how I want to execute it.
   18 // execlp("ls","ls","-l","--color=auto",NULL);
W> 19 char* const argv[]={<!-- -->"ls","-l","--color=auto",NULL};
   20 // execv("/usr/bin/ls",argv);
   21 // execvp("ls",argv);
   22 //Execute the program you wrote, the second parameter here does not need to be taken./
   23 execl("./myexe","myexe",NULL);
   24 exit(1);
   25}
   26 //parent process
   27 int status=0;
   28 pid_t ret=waitpid(id, & status,0);
   29 if(ret > 0)
   30 {<!-- -->
   31 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
   32}

Note: It is possible to execute executable programs in different languages.

 1 #include<iostream>
  2 using namespace std;
  3
  4 int main()
  5 {<!-- -->
  6 cout<<"hello C + + "<<endl;
  7 cout<<"hello C + + "<<endl;
  8 cout<<"hello C + + "<<endl;
  9 cout<<"hello C + + "<<endl;
 10 cout<<"hello C + + "<<endl;
 11 cout<<"hello C + + "<<endl;
 12 return 0;
 13}
~


You can also use python, java, etc. for replacement.

Program replacement, you can use program replacement to call the executable program corresponding to any back-end language.

2.4.5 execle

int execle(const char *path, const char *arg, …, char * const envp[]);

e: Pass in custom environment variables

 1 #include<stdio.h>
    2 #include<assert.h>
    3 #include<stdlib.h>
    4 #include<unistd.h>
    5 #include<sys/types.h>
    6 #include<sys/wait.h>
    7
    8 
    9 int main()
   10 {<!-- -->
   11 pid_t id=fork();
   12 assert(id != -1);
   13 if(id == 0)
   14 {<!-- -->
W> 15 char* const envp[]={<!-- -->(char*)"MYENV=11223344"};
   16 execle("./myexe","myexe",NULL,envp);
   17 exit(1);
   18}
   19 //parent process
   20 int status=0;
   21 pid_t ret=waitpid(id, & status,0);
   22 if(ret > 0)
   23 {<!-- -->
   24 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
   25}
   26 return 0;
 1 #include<stdio.h>
  2 #include<stdlib.h>
  3
  4 int main()
  5 {<!-- -->
  6 //The system comes with it
  7 printf("PATH:%s\
",getenv("PATH"));
  8 printf("PWD:%s\
",getenv("PWD"));
  9 //Custom environment variables
 10 printf("MYENV:%s\
",getenv("MYENV"));
 11 printf("I am a C program\
");
 12 printf("I am a C program\
");
 13 printf("I am a C program\
");
 14 printf("I am a C program\
");
 15 printf("I am a C program\
");
 16 printf("I am a C program\
");
 17 printf("I am a C program\
");
 18 printf("I am a C program\
");
 19
 20 return 0;
 twenty one }


Note that if you pass in a custom environment variable, in myexe, only the value of the custom environment variable will be displayed, and the system’s own environment variables will not be displayed.

If you want to print out the environment variables that come with the system, you need to use the environ provided by the system.

 1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8   
  9 int main()
 10 {<!-- -->
 11 pid_t id=fork();
 12 assert(id != -1);
 13 if(id == 0)
 14 {<!-- -->
 15 extern char**environ;
 16 //Even if it is not passed, the child process can obtain the environment variable
 17 execle("./myexe","myexe",NULL,environ);
 18 //Both writing methods are acceptable
 19 //execle("./myexe","myexe",NULL);
 20 exit(1);
 twenty one     }                                                                                                                    
 22 //parent process
 23 int status=0;
 24 pid_t ret=waitpid(id, & status,0);
 25 if(ret > 0)
 26 {<!-- -->
 27 printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);
 28 }
 29 return 0;


如果即想要显示自定义环境变量,又想要显示系统默认的环境变量,就将指定环境变量导入到系统中,也就是environ指向的环境变量表

  1 #include<stdio.h>
  2 #include<assert.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 #include<sys/types.h>
  6 #include<sys/wait.h>
  7
  8 
  9 int main()
 10 {<!-- -->
 11     pid_t id=fork();
 12     assert(id != -1);
 13     if(id == 0)
 14     {<!-- -->
 15         putenv((char*)"MYENV=11223344");//将指定环境变量导入到系统中 environ指向的环境变量表                                                                                                                         
 16         extern char**environ;                                                                                               
 17         execle("./myexe","myexe",NULL,environ);  
 18\t\t\texit(1);                                                                                                         
 19     }                                                                                                                    
 20     //父进程                                                                                                             
 21     int status=0;                                                                                                        
 22     pid_t ret=waitpid(id, & amp;status,0);                                                                                     
 23     if(ret > 0)                                                                                                          
 24     {<!-- -->                                                                                                                    
 25         printf("wait success:%d,sig number:%d,child exit code:%d\
",ret,status & amp;0x7F,(status>>8) & amp;0xFF);                   
 26     }  
 27     return 0;

我们知道可执行程序是一个文件,放在磁盘里的,要程序要运行的时候,需要加载到内存,为什么要加载呢?这是操作系统体系所决定的,cpu只会和内存打交道。那么如何加载呢?

是linux中exec*系统接口(加载器)加载的。

请问程序是先加载还是先执行main呢?
肯定是先加载


虽然前4个exec系列接口没有环境变量参数,但是子进程照样还是可以拿到系统默认的环境变量。因为地址空间有一块区域,存放命令行参数环境变量。

2.4.6execvp

int execvpe(const char *file, char *const argv[],char *const envp[]);

这个函数就不再演示了,就是增加了自动去环境变量寻找程序路径。

2.5总结

上面共学了6个进程替换函数,其实还有一个,这一个才是真正执行程序替换。


这个函数属于系统调用接口,其他exec系列接口都是对其封装,主要是为了满足不同的应用场景。

自此关于进程等待,进程替换内容结束了,这篇博文比较长。喜欢的点赞,评论,收藏 + 关注! ! !