Linux fork函数具体图解-同一时候分析一道腾讯笔试题
原创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函数具体图解-同一时候分析一道腾讯笔试题的更多相关文章
- linux fork函数与vfork函数,exit,_exit区别
man vfork: NAME vfork - create a child process and block parent SYNOPSIS #include <sys/types.h> ...
- linux fork()函数
C语言编程创建函数fork() 执行解析 | 浏览:1842 | 更新:2013-04-22 15:12 | 标签:c语言 概述 最近在看进程间的通信,看到了fork()函数,虽然以前用过,这次经过思 ...
- linux fork()函数 转载~~~~
转自 :: http://blog.csdn.net/jason314/article/details/5640969 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork ...
- Linux—fork函数学习笔记
fork()函数 在赋值语句pid = fork();之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的代码部分完全相同.> 两个进程中,原先就存在的那个被 ...
- linux fork函数与vfork函数
一.fork1. 调用方法#include <sys/types.h>#include <unistd.h> pid_t fork(void);正确返回:在父进程中返回子进程的 ...
- linux fork函数浅析
#include <sys/types.h> #include <unistd.h> /* 功能:复制进程 參数:无 返回值: 成功: 父进程:返回子进程id 子进程:返回0 ...
- 《linux内核分析》第六周:分析fork函数对应的系统调用处理过程
一. 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 进程是 ...
- Linux C 中 fork() 函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork() 函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同 ...
- linux的fork函数
fork函数 头文件:#include<unistd.h> 函数原型:pid_t fork( void);(pid_t 是一个宏定义,其实质是int 被定义在#include< ...
随机推荐
- HDU-1829 A Bug's Life。并查集构造,与POJ1709异曲同工!
A Bug's Life Find them, Catch them 都是并查集构造的题,不久前 ...
- Codeforces Round #358 (Div. 2)——C. Alyona and the Tree(树的DFS+逆向思维)
C. Alyona and the Tree time limit per test 1 second memory limit per test 256 megabytes input standa ...
- [BZOJ4756] [Usaco2017 Jan]Promotion Counting(线段树合并)
传送门 此题很有意思,有多种解法 1.用天天爱跑步的方法,进入子树的时候ans-query,出去子树的时候ans+query,query可以用树状数组或线段树来搞 2.按dfs序建立主席树 3.线段树 ...
- 【2018.10.15】noip模拟赛Day1
题面 wzj的题解 T1 随便搜 #include<bits/stdc++.h> #define ll long long using namespace std; inline int ...
- 【bzoj1710】[Usaco2007 Open]Cheappal 廉价回文
[bzoj1710][Usaco2007 Open]Cheappal 廉价回文 Description 为了跟踪所有的牛,农夫JOHN在农场上装了一套自动系统. 他给了每一个头牛一个电子牌号 当牛走过 ...
- hdu4336 Card Collector(概率DP,状态压缩)
In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...
- EC++学习笔记(三) 资源管理
条款13:以对象管理资源 资源包括:动态分配内存.文件描述符.网络socket.互斥锁.数据库连接 把资源放进对象内,可以依赖c++的"析构函数自动调用机制"确保资源被释放智能指针 ...
- Codeforces 864E Fire(DP)
题目链接 Fire 题意 有n个物品,每个物品的挽救时间代价为ti, 消失时刻为di, 价值为pi. 如果要救某个物品,必须在他消失之前救出来. 同一时刻最多只能救一件物品. 当前耗时为当前已经救出的 ...
- 程序防止SqlServer使用SqlServer Profiler跟踪
思路: 1.使用默认函数(fn_trace_getinfo)查询跟踪列表: 2.调用系统存储过程(sp_trace_setstatus)修改跟踪状态. 相关Sql : declare @default ...
- 接口自动化测试之HTTP协议详解
协议 简单理解,计算机与计算机之间的通讯语言就叫做协议,不同的计算机之间只有使用相同的协议才能通信.所以网络协议就是为计算机网络中进行数据交换而建立的规则,标准或约定的集合. OSI模型 1978年国 ...