fork一次返回2个值,返回三类值。函数原型:pid_t fork();
正:fork父进程,返回子进程ID;
零:fork子进程,返回0;
负:fork失败。
fock函数调用一次却返回两次。向父进程返回子进程的ID,向子进程中返回0,这是因为父进程可能存在很多过子进程,所以必须通过这个返回的子进程ID来跟踪子进程,而子进程只有一个父进程,他的ID可以通过getppid取得。
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
pid_t pid;
int count=0;
pid = fork();
printf( "This is first time, pid = %d\n", pid );
printf( "This is second time, pid = %d\n", pid );
count++;
printf( "count = %d\n", count );
if (pid > 0)
{
printf( "This is the parent process,the child has the pid:%d\n", pid );
}
else if (!pid )
{
printf( "This is the child process.\n");
}
else
{
printf( "fork failed.\n" );
}
printf( "This is third time, pid = %d\n", pid );
printf( "This is fouth time, pid = %d\n", pid );
return 0;
}
结果为:
[root@localhost test]# ./testPro
This is first time, pid = 7703
This is second time, pid = 7703
count = 1
This is the parent process,the child has the pid:7703
This is third time, pid = 7703
This is fouth time, pid = 7703
This is first time, pid = 0
This is second time, pid = 0
count = 1
This is the child process.
This is third time, pid = 0
This is fouth time, pid = 0
为什么子进程打印的pid为0呢,是因为在内核里面没有直接获取子进程ID的函数,因此在父进程中使用fork返回子进程ID,子进程中返回0。
count的值还是1。是因为被fork创建的新进程叫子进程。fork函数被调用一次,却两次返回。返回值唯一的区别是在子进程中返回0,而在父进程中返回子进程的pid。在父进程中要返回子进程的pid的原因是父进程可能有不止一个子进程,而一个进程又没有任何函数可以得到他的子进程的pid。
子进程和父进程都执行在fork函数调用之后的代码,子进程是父进程的一个拷贝。例如,父进程的数据空间、堆栈空间都会给子进程一个拷贝,而不是共享这些内存。
也就是说,在Linux下一个进程在内存里有三部分的数据,就是"代码段"、"堆栈段"和"数据段"。"代码段",顾名思义,就是存放了程序代码,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。
针对Linux中的进程的5个段的说明,参考:https://blog.csdn.net/x18261294286/article/details/82926568
一个程序一旦调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。
fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上下文场景也被自动复制到子进程中,包括:
——全局和局部变量
——打开的文件句柄
——共享内存、消息等同步对象
而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat,shmdt等)来操作。现在,已经是两个进程了,对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。
查看进程:
[root@localhost test]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 7603 7580 0 80 0 - 29141 wait pts/0 00:00:00 bash
0 R 0 7713 7603 0 80 0 - 37233 - pts/0 00:00:00 ps
并没有7703的进程?why?