fork
fork创造的子进程是父进程的完整副本,复制了父亲进程的资源,包括内存的内容task_struct内容
vfork
vfork创建的子进程与父进程共享数据段,而且由vfork()创建的子进程将先于父进程运行
用fork、vfork创建进程,设计实验查看二者在分配和共享两方面的区别
(1)分别编写fork.c和vfork.c进行验证
fork.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = fork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("I am the child process,ID is %d\n",getpid());
printf("My cnt is: %d (%p)\n",cnt,&cnt);
//_exit(0);
}
else
{
cnt++;
printf("I am the parent process,ID is %d\n",getpid());
printf("My cnt is: %d (%p)\n",cnt,&cnt);
}
return 0;
}
vfork.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid<0)
printf("error in fork!\n");
else if(pid == 0)
{
cnt++;
printf("I am the child process,ID is %d\n",getpid());
printf("My cnt is: %d (%p)\n",cnt,&cnt);
_exit(0);
}
else
{
cnt++;
printf("I am the parent process,ID is %d\n",getpid());
printf("My cnt is: %d (%p)\n",cnt,&cnt);
}
return 0;
}
(2)对程序编译
(3)运行程序
运行./fork
fork()函数用于从已存在的进程中创建一个新的进 程,新的进程称为子进程,而原进程称为父进程,fork ()的返回值有两个,子进程返回0, 父进程返回子进程的进程号,进程号都是非零的正整数,所以父进程返回的值一定大于零, 在pid=fork();语句之前只有父进程在运行,而在pid=fork();之后,父进程和新创建的子进程 都在运行,所以如果pid==0,那么肯定是子进程,若pid !=0 (事实上肯定大于0),那么是 父进程在运行。
在fork之前,只有父进程运行,之后子进程也开始运行,两个进程均运行,在各自的内存中cnt加1,括号中的地址相同是因为虚拟地址是相同的,但是实际内存地址是不同的。fork出的子进程不与父进程共享内存。
运行./vfork
vfork 保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
vfork()子进程与父进程共享内存,在子进程中cnt加1并退出后,父进程运行cnt再加1,最后的cnt为2。
欢迎批评指正!