关于进程创建fork函数的理解

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?

发布了91 篇原创文章 · 获赞 75 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/fengxianghui01/article/details/99735974