操作系统 之 fork 函数 概念篇 悠悠 2022-08-05 07:50 130阅读 0赞 由fork创建的新进程被称为子进程(child process)。**该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0**,而**父进程的返回值则是新进程(子进程)的进程 id。将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id**。对子进程来说,之所以fork返回0给它,是因为它随时可以调用**getpid()来获取自己的pid;也可以调用getppid()来获取父进程的id**。(进程id 0总是由交换进程使用,所以,**一个子进程的进程id不可能为0** )。 fork之后,**操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,子进程拥有父进程当前运行到的位置**(两进程的程序计数器pc值相同,也就是说,子进程是从fork返回处开始执行的),但有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,**如果fork不成功,父进程会返回错误。** 可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因 至于哪一个最先运行,可能与操作系统(调度算法)有关,而且这个问题在实际应用中并不重要,如果需要父子进程协同,可以通过原语的办法解决。 头文件: \#include<unistd.h> \#include<sys/types.h> 函数原型: pid\_t fork( void); (pid\_t 是一个宏定义,其实质是int 被定义在\#include<sys/types.h>中) 返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1。 注意,子进程是父进程的副本,拷贝父进程的数据空间,堆栈等资源。父子进程不共享上述资源。 每执行一次fork()函数,会返回两次,一次是在父进程,一次是在子进程,两次的返回值不一样。 【函数用例】 #include<unistd.h> #include<sys/types.h> #include<stdio.h> #include<stdlib.h> int main(int argc, char ** argv ) { pid_t result = fork(); if(result < 0) { printf("Error"); } else if(result == 0) { printf("From the son"); } else { printf("From the father"); } } 输出 From the son From the father 可以看到,父子进程都同时执行了这段代码。可以这么理解,子进程拷贝父进程的所有代码,和堆栈,然后从fork()的下一行,子进程执行。
还没有评论,来说两句吧...