一. vfork
區別:
1. fork:子進程拷貝父進程的數據段
vfork:子進程與父進程共享數據段
2. fork:父、子進程的執行次序不確定
vfork:子進程先運行,父進程後運行
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int i = 0;
pid = vfork();
if(pid == 0)
{
printf("son:\n");
i++;
printf("%d\n",i);
return 0;
}
else
{
printf("parent\n");
i++;
printf("%d\n",i);
return 0;
}
}
程序運行結果:
son:
1
parent
1
段錯誤
爲什麼會出現段錯誤?爲什麼父進程輸出1?
分析:子進程中 return 0 (返回調用的函數)執行後釋放程序所有資源,此時i已經釋放。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int i = 0;
pid = vfork();
if(pid == 0)
{
printf("son:\n");
i++;
printf("%d\n",i);
exit(0);
}
else
{
printf("parent\n");
i++;
printf("%d\n",i);
return 0;
}
}
程序運行結果:
son:
1
parent
2
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid = vfork();
int i = 0;
if(pid == 0)
{
printf("son:\n");
i++;
printf("%d\n",i);
exit(0);
}
else
{
printf("parent\n");
i++;
printf("%d\n",i);
return 0;
}
}
程序運行結果:
son:
1
parent
1
二. 正確的畫出進程樹
/************************************************************************
Funcion List:
能正確的畫出進程樹
i son/par ppid pid fpid
0 child 20474 20475 0
1 child 20475 20476 0
1 parent 20474 20475 20476
0 parent 17732 20474 20475
1 child 20474 20477 0
1 parent 17732 20474 20477
*************************************************************************/
int main()
{
int i;
printf("\ti\tson/par\t\tppid\tpid\tfpid\n");
for(i =0; i < 2; i++)
{
pid_t fpid;
fpid = fork(); //創建子進程
if(fpid == 0 )
{
printf("\t%d\tchild\t\t%d\t%d\t%d\n",i,getppid(),getpid(),fpid);
}
else
{
printf("\t%d\tparent\t\t%d\t%d\t%d\n",i,getppid(),getpid(),fpid);
}
}
return 0;
}
/************************************************************************
20474 20474
17732 20477
20475 20475
20476
*************************************************************************/
三. exec函數族 和 system 函數
#include <unistd.h>
#include <stdio.h>
int main()
{
execl("/bin/ls","ls","-al","/home",NULL);
printf("*********************\n");
return 0;
}
#include <unistd.h>
#include <stdio.h>
int main()
{
execl("/home/1120/hello","./hello","1","2",NULL);
printf("***********\n");
return 0;
}
但是在shell腳本中, ./hello 1 2 "./hello" 既是命令也是參數
#include <unistd.h>
#include <stdio.h>
int main()
{
char * argv[] = {"./hello","1","2",NULL};
execv("/home/1120/hello",argv);
printf("***********\n");
return 0;
}
#include <unistd.h>
#include <stdio.h>
int main()
{
system("/home/1120/hello 1 2 ");
printf("***********\n");
return 0;
}