fork() 函数

头文件:

#include<unistd.h>

#include<sys/types.h>

函数定义:

pid_t fork(void);

pid_t只是一个typedef定义,在不同的平台下可能是不同的数据类型(short, int , long),只是为了令可移植性好一些,其定义在文件 sys/types.h中。

函数返回值:

在父进程当中,返回子进程的ID,在子进程当中,返回0,失败返回-1.

函数说明:

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是父进程中返回子进程ID,而子进程中返回0值。

我们可以利用返回值的这一特性,来确定当前是处于子进程还是父进程当中。

if ((retValue = fork()) == 0) // 0,当前位于子进程当中,执行子进程的代码

{

   // 子进程需要处理的任务

   /* ... */

   exit(0); // 结束子进程

}  


子进程具有独立的地址空间,进程调用fork()之后,系统会给子进程分配新的资源。

fork的另一个特性是所有由父进程打开的描述符(descriptor,如file,socket等)都被复制到子进程中。父、子进程中相同编号的描述符在内核中指向同一个结构体,也就是说,仅仅是描述符结构体的引用计数要增加。

在调用fork之前,只有一个进程在执行代码,但之后将会有两个进程同时执行(父子),这两个进程几乎完全相同,将要执行的下一条语句都是fork()后面的那条语句。

例如:

int main ()   
{   
    pid_t fpid; 
    int count=0;  
    fpid=fork();   
    if (fpid < 0)   
        printf("error in fork!");   
    else if (fpid == 0) {  
        printf("i am the child process, my process id is %d/n",getpid());   
        printf("我是爹的儿子/n");  
        count++;  
    }  
    else {  
        printf("i am the parent process, my process id is %d/n",getpid());   
        printf("我是孩子他爹/n");  
        count++;  
    }  
    printf("统计结果是: %d/n",count);  
    return 0;  
} 

运行结果是:
    i am the child process, my process id is 5574
    我是爹的儿子
    统计结果是: 1
    i am the parent process, my process id is 5573
    我是孩子他爹
    统计结果是: 1


在语句 fpid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程几乎完全相同,将要执行的下一条语句都是if(fpid<0)……


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


创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略.


为什么fork不从main函数开始执行?

这致是fork的约定,fork()将进程的内存完全复制一份给子进程,所有程序的上下文和内存变量都是一致的,因此新的程序还是从fork下一句开始执行,需要根据fork的返回值判断当前是在父进程还是子进程。


fork() 子进程的terminate及僵尸(Zombie)进程的处理... ....(未完)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值