原创blog。转载请注明出处

头文件:

#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()的下一行,子进程运行

再看一个样例

代码

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char ** argv )
{
int i;
for(i = 0;i < 2;i++)
{
fork();
printf("%d\n",i);
}
}

然后我们编译运行

运行的结果是

[root@localhost test]# gcc -o first first.c
[root@localhost test]# ./first
0
1
1
0
1
1

为了便于分析,我们每次都输出当前进程的ppid(父进程)以及当前进程的pid

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char ** argv )
{
int i;
for(i = 0;i < 2;i++)
{
fork();
printf("%d PPID:%d PID:%d\n",i,getppid(),getpid());
}
}

结果

[root@localhost test]# ./first
0 PPID:4984 PID:4985
1 PPID:4985 PID:4986
1 PPID:4984 PID:4985
0 PPID:4424 PID:4984
1 PPID:4984 PID:4987
1 PPID:4424 PID:4984

先分析PID。一共同拥有4种,所以一共同拥有4984,4985,4986,4987四个进程,所以4424是最開始的进程(main)的父进程,所以。最開始的进程是4984

然后根据pid来梳理进程的父子关系

依照子进程->父进程

4986->4985->4984->4424

4987->4984->4424

所以依照这个关系,我们绘图来分析比較直观

当中,输出的顺序依照红色圈中顺序来输出

由图能够看出,在我的这个CentOS系统中,子进程比父进程先运行,运行顺序在不同系统中不一样。所以编程的时候应当不依赖运行某一个系统的顺序。

然后,我们来分析一道经典的笔试面试题

     for(i = 0;i < 2;i++)
{
fork();
printf("%d\n",i);
}
}

  for(i = 0;i < 2;i++)
{
fork();
printf("%d",i);
}
}

各输出了几个0,几个1

对于前者

输出是

0
1
1
0
1
1

对于后者

输出是

01010101

对于前者,在上面已经进行了图解。所以不难理解。对于后者,不少同学会非常奇怪,为什么输出了4个0,4个1?

原因是:C语言中,printf函数假设遇到\n,会马上输出缓冲区内全部内容,假设没有\n,会先输出到缓冲区内。等待输出

我们继续绘图来分析,

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSGVsbG9fSHdj/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

这里在详解下:能够这么理解,每次printf的时候,是把本进程的printf缓冲区,增加到总的printf缓冲区(这样的说法可能不严谨)。比方到红色圈圈3的时候。4985本身在红色圈圈1的时候缓冲区已经有0了。那么再增加1,则本身进程的缓冲区为01,那么增加到printf总的缓冲区就是0101

原创blog,转载请注明出处

Linux fork函数具体图解-同一时候分析一道腾讯笔试题的更多相关文章

  1. linux fork函数与vfork函数,exit,_exit区别

    man vfork: NAME vfork - create a child process and block parent SYNOPSIS #include <sys/types.h> ...

  2. linux fork()函数

    C语言编程创建函数fork() 执行解析 | 浏览:1842 | 更新:2013-04-22 15:12 | 标签:c语言 概述 最近在看进程间的通信,看到了fork()函数,虽然以前用过,这次经过思 ...

  3. linux fork()函数 转载~~~~

    转自  ::  http://blog.csdn.net/jason314/article/details/5640969  一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork ...

  4. Linux—fork函数学习笔记

    fork()函数 在赋值语句pid = fork();之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的代码部分完全相同.> 两个进程中,原先就存在的那个被 ...

  5. linux fork函数与vfork函数

    一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...

  6. linux fork函数浅析

    #include <sys/types.h> #include <unistd.h> /* 功能:复制进程 參数:无 返回值: 成功: 父进程:返回子进程id 子进程:返回0 ...

  7. 《linux内核分析》第六周:分析fork函数对应的系统调用处理过程

    一. 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 进程是 ...

  8. Linux C 中 fork() 函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork() 函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同 ...

  9. linux的fork函数

       fork函数  头文件:#include<unistd.h> 函数原型:pid_t fork( void);(pid_t 是一个宏定义,其实质是int 被定义在#include< ...

随机推荐

  1. 4C. Stars

    4C. Stars Time Limit: 2000ms Case Time Limit: 2000ms Memory Limit: 65536KB   64-bit integer IO forma ...

  2. tomcat404

    确认目录下有我的html文件,但仍然是404. 问题一: 指定目录下没有访问的文件,这是最常见的,也是最容易解决的.只需要将访问的文件(如:a.html)放到指定目录下即可. 问题二: 将访问的文件( ...

  3. POJ——3984迷宫问题(BFS+回溯)

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14568   Accepted: 8711 Description ...

  4. 「SDOI2010」古代猪文(bzoj1951)

    题目写了一大堆背景. 一句话题意就是求 $q^{\sum_{d|n}C_{n}^{d}} \mod 999911659$. 因为$n$是质数,只有当$q$是$n$的倍数时(此题数据范围原因,最多$q= ...

  5. 在GridView中的每一页末尾添加空行

    原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] protected void GridView1_RowCreated(object sender, GridVi ...

  6. FastDFS上传/下载过程[转载-经典图列]

    FastDFS上传/下载过程: 首先客户端 client 发起对 FastDFS 的文件传输动作,是通过连接到某一台 Tracker Server 的指定端口来实现的,Tracker Server 根 ...

  7. 动态添加radiogroup

    private LinearLayout layout; //布局 , 可以在xml布局中获得 private RadioGroup group ; //点选按钮组 public void onCre ...

  8. HDU 1242 dFS 找目标最短路

    //多个起点,要最短得目标,不妨倒过来从目标出发,去找最近的点更新!!!!!!递归时思路要清楚 #include<iostream> #include<cstring> usi ...

  9. (1)Swing创建窗体

    本系列使用Intellij IDEA 2017.3.4版本 一.运行窗体 1. 2. 3. 4. 5. 6. 给JPanel起个名字 -如From 7. 8. 9. 生成 import javax.s ...

  10. Python 和 Elasticsearch 构建简易搜索

    Python 和 Elasticsearch 构建简易搜索 作者:白宁超 2019年5月24日17:22:41 导读:件开发最大的麻烦事之一就是环境配置,操作系统设置,各种库和组件的安装.只有它们都正 ...