1 Executing a Programing
- exec将加载新的进程,并替换掉现在的进程
exev
execvp
execvpe
- exev
- execvp
- execvpe
1.1 Using execv and execvp
- execv,需要输入绝对路径
/*execv_ls-l.c*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char * argv[]){
//argv array for: /bin/ls -l
char * ls_args[] = { "/bin/ls" , "-l", NULL};
// ^
// all argv arrays must be ___|
// NULL terminated
//execute the program
execv( ls_args[0], ls_args);
// ^ ^
// | |
// Name of program argv array
// is ls_args[0] for ls_args
//only get here on error
perror("execv");
return 2;
}
- execvp,可以加载
$path
,所以不需要输入全路径
aviv@saddleback: demo $ cat execvp_ls-l.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char * argv[]){
//argv array for: ls -l
char * ls_args[] = { "ls" , "-l", NULL};
// ^
// use the name ls
// rather than the
// path to /bin/ls
execvp( ls_args[0], ls_args);
//only get here on error
perror("execv");
return 2;
}
1.2 The argv[] argument to execv and execvp
char * ls_args[] = { "ls" , "-l", NULL};
.-----.
ls_args -> | .--+--> "/bin/ls"
|-----|
| .--+--> "-l"
|-----|
| .--+--> NULL
'-----'
2 Creating a new Process
1.exec是在当前进程里执行,fork是新创建了一个进程
2.1 fork()
1.所有的进程都产生于其他进程,最初的进程是init
2.fork方法返回两次,一次是父进程(返回子进程的id),一次是子进程(返回0)
3.子进程时父进程的镜像
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
pid_t c_pid;
c_pid = fork(); //duplicate
if( c_pid == 0 ){
//child: The return of fork() is zero
printf("Child: I'm the child: %d\n", c_pid);
}else if (c_pid > 0){
//parent: The return of fork() is the process of id of the child
printf("Parent: I'm the parent: %d\n", c_pid);
}else{
//error: The return of fork() is negative
perror("fork failed");
_exit(2); //exit failure, hard
}
return 0; //success
}
2.2 Process identifiers or pid
1.每一个进程都有一个id,叫pid
2.pid
占用2个字节,类型是pid_t
3.父进程fork
返回子进程的id,子进程fork
返回0,出错fork
返回-1
4.pstree 查看进程的继承关系
2.3 Retrieving Process Identifiers: getpid() and getppid()
fork
机制,父知道子pid,子不知道父pid,使用getppid
- 父不知道自己的id,使用
getpid
- shell执行进程,就是
fork
- shell是进程的父进程,使用
echo $$
来查看当前shell的进程
//retrieve the current process id
pid_t getpid(void);
//retrieve the parent's process id
pid_t getppid(void);
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
pid_t pid, ppid;
//get the process'es pid
pid = getpid();
//get the parrent of this process'es pid
ppid = getppid();
printf("My pid is: %d\n",pid);
printf("My parent's pid is %d\n", ppid);
return 0;
}
3 Waiting on a child with wait()
wait()
父进程调用,返回子进程状态的变化- 当父进程调用
wait()
将会阻塞,直到子进程状态发生变化 wait
返回子子进程的pid,如果没有子进程,则返回-1wait
需要整型指针参数,记录子进程退出的状态
/*get_exitstatus.c*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
pid_t c_pid, pid;
int status;
c_pid = fork(); //duplicate
if( c_pid == 0 ){
//child
pid = getpid();
printf("Child: %d: I'm the child\n", pid, c_pid);
printf("Child: sleeping for 2-seconds, then exiting with status 12\n");
//sleep for 2 seconds
sleep(2);
//exit with statys 12
exit(12);
}else if (c_pid > 0){
//parent
//waiting for child to terminate
pid = wait(&status);
if ( WIFEXITED(status) ){
printf("Parent: Child exited with status: %d\n", WEXITSTATUS(status));
}
}else{
//error: The return of fork() is negative
perror("fork failed");
_exit(2); //exit failure, hard
}
return 0; //success
}