1.首先我们先来了解一下fork创建进程:
(1)使用fork函数创建一个进程,pid_t fork(void)
,
fork函数调用成功的话,返回两次
返回值为0, 代表当前进程是子进程。
返回值为非负数,代表当前进程是父进程。
调用失败的话,返回-1。
重要提示:调用fork函数时,父进程的返回值就是子进程的进程ID,而子进程的返回值是0;
(2)fork函数创建一个子进程的一般目的
(3)fork编程实战
(4)直接上代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid1;
pid_t pid2;
pid_t retpid;
pid1 = getpid();
printf("before fork the pid1:%d\n",pid1);
retpid = fork();
pid2 = getpid();
printf("after the fork the pid2:%d\n",pid2);
if(pid1 == pid2)
{
printf("this is father process,the pid is:%d,the retpid is:%d\n",pid1,retpid);
}
else if(pid1 != pid2)
{
printf("this is child process,the pid is:%d,the retpid is:%d\n",pid2,retpid);
}
return 0;
}
结果:
从结果中可以看出,父子进程是交换执行的。
(5)fork函数创建的子进程与父进程的内存关系
(6)证明fork函数创建的子进程跟父进程并不是共用存储空间的
直接上代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int data = 0;
pid = fork();
if(pid > 0)
{
while(1){
data++;
printf("data = %d\n",data);
printf("this is father process\n");
sleep(3);
}
}
else if(pid == 0)
{
while(1){
data++;
printf("data = %d\n",data);
printf("this is child process\n");
sleep(3);
}
}
return 0;
}
结果:
从以上结果我们看到在父进程跟子进程里的data值是不叠加的,而是各自加各自的,所以我们可以知道fork方式创建的子进程是不跟父进程共用存储空间的。
2.介绍完fork创建进程,接下来我们来介绍一下用vfork函数来创建进程;
(1)使用vfork创建一个进程:pid_t vfork(void);
(2)vfork()创建进程与fork()创建进程的区别;
区别一,vfork直接使用父进程的存储空间,不进行拷贝,(说白了就是与父进程共用一段内存空间)
区别二,vfork保证子进程先运行,当子进程调用exit()退出后,父进程才执行,而fork是父子进程交替 执行。
(3)vfork的返回值
vfork函数调用成功的话,返回两次
返回值为0, 代表当前进程是子进程。
返回值为非负数,代表当前进程是父进程。
调用失败的话,返回-1。
返回值其实是跟fork是一模一样的,只不过是父进程先让子进程先运行,子进程调用exit函数退出后再到父进程,父进程的返回值依然是子进程的ID号。
(4)闲话不多说,直接上的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid > 0)
{
while(1)
{
printf("this is father process,the pid is :%d\n",pid);
sleep(3);
printf("cnt = %d\n",cnt);
}
}
else if(pid == 0)
{
while(1)
{
printf("this is child process,pid = %d\n",getpid());
sleep(3);
cnt++;
if(cnt > 3)
{
exit(0);
}
}
}
return 0;
}
结果:
从结果中我们可以看出最主要的一点就是父进程中的cnt的值是接着子进程的累加上来的,这就说明了vfork方式创建的子进程是跟父进程共用一段存储空间的,而且父进程的返回值依然是子进程的ID号(虽然是子进程先运行)。
学习笔记,仅供参考。