您的位置:首页 > 其它

关于fork()函数的两个返回值

2014-05-10 21:40 281 查看
对于刚刚接触Unix/Linux操作系统,在Linux下编写多进程的人来说,fork是最难理解的概念之一:它执行一次却返回两个值。

首先我们来看下fork函数的原型:

#include <sys/types.h>

#include <unistd.h>

pid_t fork(void);

返回值:

负数:如果出错,则fork()返回-1,此时没有创建新的进程。最初的进程仍然运行。

零:在子进程中,fork()返回0

正数:在负进程中,fork()返回正的子进程的PID

其次我们来看下如何利用fork创建子进程。

创建子进程的样板代码如下所示:

pid_t child;

if((child = fork())<0)

/*错误处理*/

else if(child == 0)

/*这是新进程*/

else

/*这是最初的父进程*/

fock函数调用一次却返回两次;向父进程返回子进程的ID,向子进程中返回0,

这是因为父进程可能存在很多过子进程,所以必须通过这个返回的子进程ID来跟踪子进程,

而子进程只有一个父进程,他的ID可以通过getppid取得。

下面我们来对比一下两个例子:

第一个:

#include <unistd.h>

#include <stdio.h>

int main()

{

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;

}

运行结果如下:

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

This is first time, pid = 4896

This is second time, pid = 4896

count = 1

This is the parent process,the child has the pid:4896

This is third time, pid = 4896

This is fouth time, pid = 4896

问题:

这个结果很奇怪了,为什么printf的语句执行两次,而那句“count++;”的语句却只执行了一次

现在来解释上面提出的问题。

看这个程序的时候,头脑中必须首先了解一个概念:在语句pid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的代码部分完全相同,将要执行的下一条语句都是if ( pid>0 )……。

两个进程中,原先就存在的那个被称作“父进程”,新出现的那个被称作“子进程”。父子进程的区别除了进程标志符(process ID)不同外,变量pid的值也不相同,pid存放的是fork的返回值。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

1. 在父进程中,fork返回新创建子进程的进程ID;

2.在子进程中,fork返回0;

3.如果出现错误,fork返回一个负值;

fork出错可能有两种原因:(1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。(2)系统内存不足,这时errno的值被设置为ENOMEM。

也就是说,在Linux下一个进程在内存里有三部分的数据,就是"代码段"、"堆栈段"和"数据段"。"代码段",顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。"堆栈段"存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐