1、init进程
每个进程都会分配一个唯一的数字编号,我们称之为进程标识符或者PID,它通常是一个取值范围从2到32768的正整数。数字1是为特殊进程init保留的。linux系统启动时,它将运行一个名为init的进程,该进程是系统运行的第一个进程,它是其他所有进程的祖先进程。
2、替换进程映像
The exec family of functions replaces the current process image with a new process image.
(1)int execl(const char *path, const char *arg0, ...,(char *)0); (2)int execlp(const char *file, const char *arg, ...,(char *)0); (3)int execle(const char *path, const char *arg , ...(char *)0, char * const envp[]); (4)int execv(const char *path, char *const argv[]); (5)int execvp(const char *file, char *const argv[]);
它们只是参数的类型不同而已
execl中的l表示list,即它的参数是列表形式的
execv中的v表示vector,即它的参数是数组形式的
//unistd的意思是Unix Standard的意思 //文件temp.c #include<unistd.h> #include<stdio.h> int main(void) { printf("running ps with execlp\n"); execlp("ps", "ps", "ax", 0); printf("done\n"); return 0; }
运行这个程序,我们会看到先输出running ps with execlp,然后输出ps的输出信息,最后并没有输出done
并且也没有出现temp进程的信息,因为execlp("ps", "ps", "ax", 0);用ps进程替换了temp进程。
再看一些其他的例子:
#include<unistd.h> // example of a argument list, note that we need a program name for argv[0] char * const ps_argv[]={"ps", "ax", 0}; execl("/bin/ps", "ps", "ax", 0); execlp("ps", "ps", "ax", 0); // assume /bin is in PATH execv("/bin/ps", ps_argv); execvp("ps", ps_argv);
3、复制进程映像
fork创建一个新进程,这个系统调用复制当前进程,在进程表中创建一个新的表项,新的表项中的许多属性与当前进程是相同的。
#include<sys/types.h> #include<unistd.h> #include<stdio.h> int main(void) { pid_t pid; char *message; int n; printf("fork program starts\n"); pid = fork(); switch(pid) { case -1: printf("error\n"); return -1; case 0: message = "this is child"; n=5; break; default: message = "this is parent"; n=3; break; } for(; n>0;n--) { puts(message); sleep(1); } return 0; } 输出 zzj@zzj-PC ~/tmp $ ./tmp fork program starts this is parent this is child this is parent this is child this is parent this is child this is child zzj@zzj-PC ~/tmp $ this is child
4、等待一个进程
#include<sys/types.h> #include<sys/wait.h> #include<unistd.h> #include<stdio.h> #include<stdlib.h> int main(void) { pid_t pid; char *message; int n; int exit_code; printf("fork program starts\n"); pid = fork(); switch(pid) { case -1: printf("error\n"); return -1; case 0: message = "this is child"; n=5; exit_code = 100; break; default: message = "this is parent"; n=3; exit_code = 0; break; } for(; n>0;n--) { puts(message); sleep(1); } if(pid != 0) { int stat_val; pid_t child_pid; child_pid = wait(&stat_val); printf("child has finished :PID=%d\n", child_pid); if(WIFEXITED(stat_val)) { printf("child exited with code %d\n",WEXITSTATUS(stat_val)); } else { printf("child terminated abnormally\n"); } } exit(exit_code); return 0; }
父进程用wait系统调用将自己的执行挂起,直到子进程的状态信息出现为止