一、什么是进程? 就是操作系统为了实现某些功能进行的分身术,生成的子进程可以进行相应的工作
创建进程最基本的调用是fork
1 2 3 # include <unistd.h> pid_t fork (void ) ;pid_t vfork (void ) ;
调用 fork 时,系统将创建一个与当前进程相同的新进程。通常将原有的进程称为父进程,把新创建的进程称为子进程。子进程是父进程的一个拷贝,子进程获得同父进程相同的数据,但是同父进程使用不同的数据段和堆栈段。子进程从父进程继承大多数的属性,但是也修改一些属性,下表对比了父子进程间的属性差异:
fork 函数的特点是 “调用一次,返回两次”:在父进程中调用一次,在父进程和子进程中各返回一次。 在父进程中返回时的返回值为子进程的 PID,而在子进程中返回时的返回值为 0,并且返回后都将执行 fork 函数调用之后的语句。如果 fork 函数调用失败,则返回值为 -1
了。来看个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main (void ) { pid_t pid; char *message; int n; pid = fork(); if (pid < 0 ) { perror("fork failed" ); exit (1 ); } if (pid == 0 ) { printf ("This is the child process. My PID is: %d. My PPID is: %d.\n" , getpid(), getppid()); } else { printf ("This is the parent process. My PID is %d.\n" , getpid()); } return 0 ; }
如果要在子进程中执行命令的话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main (void ) { pid_t pid; if ((pid=vfork()) < 0 ) { printf ("vfork error!\n" ); exit (1 ); } else if (pid==0 ) { printf ("Child process PID: %d.\n" , getpid()); char *argv[ ]={"ls" , "-al" , "/home" , NULL }; char *envp[ ]={"PATH=/bin" , NULL }; if (execv("/bin/ls" , argv, envp) < 0 ) { printf ("subprocess error" ); exit (1 ); } printf ("You should never see this message." ); } else { printf ("Parent process PID: %d.\n" , getpid()); sleep(1 ); } return 0 ; }