赞
踩
对于刚刚接触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之类的函数取得的空间)。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。