fork函数
fork函数为了创建新的子进程,fork函数被执行一次,但是返回值有两个,一个在父进程中返回,一个在子进程中返回,返回值在子进程中是0, 在父进程中是创建的子进程的PID, 在父进程中返回子进程的PID的原因是, 一个父进程可以有多个子进程, 然而没有方法通过其他方式获取子进程的PID, 为了对子进程有控制权, 所以在父进程中返回子进程的PID, fork出来的子进程会拷贝父进程的内存, 但是代码段这部分不会被拷贝到子进程, 因为子进程和父进程的代码段都相同, 且不会又修改, 现在的操作系统为了提高效率, 采用了COW(copy on write), 即在写入的时候, 为了保持父进程和子进程的内存独立性, 会拷贝即将要写入的内存, 比如父进程要修改自己内存的某一个值, 此时就会将这个值所在的内存提前拷贝到子进程的内存空间, 这样父进程修改内存数据就不会对子进程的内存产生影响, 保证了fork出来的子进程内存和父进程内存的独立。
一个例子:
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid;
int count=0;
fpid=fork();
if (fpid < 0) {
printf("error in fork!");
}
else if (fpid == 0) {
printf("child count : %d\n",count);
printf("i am the child process, my process id is %d\n",getpid());
count++;
}
else {
printf("parent count : %d\n",count);
printf("i am the parent process, my process id is %d\n",getpid());
}
return 0;
}
结果是:
parent count : 0
i am the parent process, my process id is 11
child count : 0
i am the child process, my process id is 12
子进程修改了count数值,由于COW,保证了两个内存的独立性,所以结果如上。
fork函数和File Shareing
直接上图:
父进程和子进程的文件表项是不同的,但是所指向的文件指针是相同的(存在内核内存中)。
vfork函数
vfork函数返回值和fork一样,只不过和fork函数不同的是,vfork会拷贝父进程的内存,所以父进程和子进程共享同样的内存
来一个例子:
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
fpid=vfork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n",getpid());
count++;
printf("count : %d\n",count);
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
printf("count : %d\n",count);
}
return 0;
}
结果是:
i am the child process, my process id is 2424
count : 1
i am the parent process, my process id is 2423
count : 0
这里有一个注意的地方是,当子进程调用exit函数才共享父进程的内存,上述没有调用exit函数,所以结果有偏差,这里改一下:
#include <unistd.h>
#include <stdio.h>
int main ()
{
pid_t fpid; //fpid表示fork函数返回的值
int count=0;
fpid=vfork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n",getpid());
count++;
printf("count : %d\n",count);
_exit(0);
}
else {
printf("i am the parent process, my process id is %d\n",getpid());
printf("count : %d\n",count);
}
return 0;
}
结果是:
i am the child process, my process id is 2465
count : 1
i am the parent process, my process id is 2464
count : 1