一. 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;
}