调用fork时,fork 创造的子进程复制了父亲进程的资源,包括内存的内容task_struct内容,新旧进程使用同一代码段,复制数据段和堆栈段,这里的复制采用了注明的copy_on_write技术,即一旦子进程开始运行,则新旧进程的地址空间已经分开,两者运行独立运行。
调用vfork时,在调用exec函数和exit函数之前,子进程和父进程共享数据段数据。vfork函数创建的子进程完全运行在父进程的地址空间上,子进程对虚拟地址空间任何数据的修改都为父进程所见。在vfork时,先运行子进程,阻塞父进程运行。
如下面的程序:
int status;
int number = 0;
pid_t cpid;
cpid = fork();
if(cpid == 0) //child thread
{
char *argv[]={"ls","-la",NULL};
number = 5;
printf("in child %d number=%d\n",getpid(),number);
int ret =execv("/bin/ls",argv);
if(ret == -1)
{
printf("exit error");
perror("exit");
_exit(100);
}
// printf(" ret = %d before exit\n",ret);
}
else //father thread
{
printf("in father %d number=%d\n",getpid(),number);
waitpid(cpid,&status,0);
}
printf("wait pid status=%d\n",status);
因为使用的是fork,这里in child %d number=5,但是in father %d number=0;
如果是的是vfork,in father %d number=5和in child %d number=5相同。
2、如果调用exec函数,执行其他的进程,建议使用vfork,节省时间和资源。
3、在调用exec函数的时候,如果exec有返回,则是返回错误,错误代码在errno中,用perror打印,否则没有返回值,执行完成命令之后,直接退出线程。如上例子中,如果exec正确执行,printf(" ret = %d before exit\n",ret);则不会执行。