1、linux fork和vfork的區(qū)別:
調(diào)用fork時(shí),fork 創(chuàng)造的子進(jìn)程復(fù)制了父親進(jìn)程的資源,包括內(nèi)存的內(nèi)容task_struct內(nèi)容,新舊進(jìn)程使用同一代碼段,復(fù)制數(shù)據(jù)段和堆棧段,這里的復(fù)制采用了注明的copy_on_write技術(shù),即一旦子進(jìn)程開(kāi)始運(yùn)行,則新舊進(jìn)程的地址空間已經(jīng)分開(kāi),兩者運(yùn)行獨(dú)立運(yùn)行。
調(diào)用vfork時(shí),在調(diào)用exec函數(shù)和exit函數(shù)之前,子進(jìn)程和父進(jìn)程共享數(shù)據(jù)段數(shù)據(jù)。vfork函數(shù)創(chuàng)建的子進(jìn)程完全運(yùn)行在父進(jìn)程的地址空間上,子進(jìn)程對(duì)虛擬地址空間任何數(shù)據(jù)的修改都為父進(jìn)程所見(jiàn)。在vfork時(shí),先運(yùn)行子進(jìn)程,阻塞父進(jìn)程運(yùn)行。
如下面的程序:
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);
因?yàn)槭褂玫氖莊ork,這里in child %d number=5,但是in father %d number=0;
如果是的是vfork,in father %d number=5和in child %d number=5相同。
2、如果調(diào)用exec函數(shù),執(zhí)行其他的進(jìn)程,建議使用vfork,節(jié)省時(shí)間和資源。
3、在調(diào)用exec函數(shù)的時(shí)候,如果exec有返回,則是返回錯(cuò)誤,錯(cuò)誤代碼在errno中,用perror打印,否則沒(méi)有返回值,執(zhí)行完成命令之后,直接退出線(xiàn)程。如上例子中,如果exec正確執(zhí)行,printf(" ret = %d before exit\n",ret);則不會(huì)執(zhí)行。
聯(lián)系客服