新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > FORK()函数的理解

FORK()函数的理解

作者:时间:2012-08-06来源:网络收藏

子进程和父进程都执行在fork调用之后的代码,子进程是父进程的一个拷贝。例如,父进程的数据空间、堆栈空间都会给子进程一个拷贝,而不是共享这些内存。

Current implementations don't perform. a complete copy of the parent's data, stack, and heap, since a fork is often followed by an exec. Instead, a technique called copy-on-write (COW) is used. These regions are shared by the parent and the child and have their protection changed by the kernel to read-only. If either process tries to modify these regions, the kernel then makes a copy of that piece of memory only, typically a page in a virtual memory system. Section 9.2 of Bach [1986] and Sections 5.6 and 5.7 of McKusick et al. [1996] provide more detail on this feature.

我们来给出详细的注释

#include

#include

int main(void)

{

pid_t pid;

int count=0;

/*此处,执行fork调用,创建了一个新的进程, 这个进程共享父进程的数据和堆栈空间等,这之后的代码指令为子进程创建了一个拷贝。 fock 调用是一个复制进程,fock 不象线程需提供一个做为入口, fock调用后,新进程的入口就在 fock的下一条语句。*/

pid = fork();

/*此处的pid的值,可以说明fork调用后,目前执行的是父进程还是子进程*/

printf( Now, the pid returned by calling fork() is %dn, pid );

if ( pid>0 )

{

/*当fork在子进程中返回后,fork调用又向父进程中返回子进程的pid, 如是该段代码被执行,但是注意的事,count仍然为0, 因为父进程中的count始终没有被重新赋值, 这里就可以看出子进程的数据和堆栈空间和父进程是独立的,而不是共享数据*/

printf( This is the parent process,the child has the pid:%dn, pid );

printf( In the parent process,count = %dn, count );

}

else if ( !pid )

{ /*在子进程中对count进行自加1的操作,但是并没有影响到父进程中的count值,父进程中的count值仍然为0*/

printf( This is the child process.n);

printf( Do your own things here.n );

count++;

printf( In the child process, count = %dn, count );

}

else

{

printf( fork failed.n );

}

return 0;

}

也就是说,在Linux下一个进程在内存里有三部分的数据,就是代码段、堆栈段和数据段。代码段,顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。

仔细分析后,我们就可以知道:

一个程序一旦调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。

fork()不仅创建出与父进程代码相同的子进程,而且父进程在fork执行点的所有上下文场景也被自动复制到子进程中,包括:

——全局和局部变量

——打开的文件句柄

——共享内存、消息等同步对象

而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat,shmdt等)来操作。现在,已经是两个进程了,对于父进程,fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零,这样,对于程序,只要判断fork函数的返回值,就知道自己是处于父进程还是子进程中。

pid控制相关文章:pid控制原理



上一页 1 2 下一页

关键词: 理解 函数 FORK

评论


相关推荐

技术专区

关闭