进程创建函数fork()程序举例:
#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){
message="This is the child\n";
n=6;
}else {
message="This is the parent\n";
n=3;
}
for(;n>0;n--){
printf(message);
sleep(1);
}
return 0;
}
程序执行:
在该函数中调用fork()之后,程序的执行过程如下:
即,本来该程序在执行时有一个进程,经过fork之后就有了两个进程,子进程和父进程,这两个进程都要执行,可是先后顺序就是随机的了,可能父先可能子先。
关于fork的返回值问题,在父进程中,fork的返回值为子进程的pid,在子进程中,返回值为0.
在程序的执行结果中我们注意到有的child进程是在shell提示符之后出现的,这是什么原因呢?原来,本程序是在shell下运行的,因此shell进程是父进程的父进程,父进程运行时shell进程处于等待状态,当父进程终止时shell进程就认为命令结束了,于是就打印shell提示符,而这时子进程还没有结束,所以子进程的消息打印到了shell提示符之后了。
除了fork可以创建一个进程之外,vfork也可以创建一个进程,两者有什么区别呢?
1、fork创建进程后不能指定哪个先执行,哪个后执行,而vfork之后是子进程先执行。
2、我们在使用fork创建一个子进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程。而使用vfork创建一个子进程时,操作系统并不将父进程的地址完全复制到子进程,vfork创建的子进程共享父进程的地址空间,意思就是当子进程对该地址中的任何数据修改之后,父进程中的值也会随之改变。
举一个例子
#include <unistd.h>
#include <stdlib.h>
int globVar=5;
int var=1;
int main(void)
{
pid_t pid;
int i;
printf("fork if diffrent with vfork \n");
pid=fork();
// pid=vfork();
switch(pid){
case 0:
i=3;
while(i-->0){
printf("Child process is running\n");
globVar++;
var++;
sleep(1);
}
printf("Child's globVar=%d,var=%d\n",globVar,var);
break;
case -1:
perror("Process creation failed\n");
exit(0);
default:
i=5;
while(i-->0){
printf("Parent process is running\n");
globVar++;
var++;
sleep(1);
}
printf("Parent's globVar=%d,var=%d\n",globVar,var);
exit(0);
}
return 0;
}
这里使用fork创建一个新的进程,结果如下:
alobVar和var的值在每个进程中都是单独计算的,现在把vfork()的注释去掉,并把fork()注释掉,再次执行程序:
可以看到,父进程是在子进程的基础上计算的值。