一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

Test1

for(int i = 0; i<2; i++)
{
if(fork() == 0)
printf("A\n");
else
printf("B\n");
}

上述代码中,fork() 执行后会出现两个进程,子进程中的 fork() 返回值为 0,父进程中 fork() 返回值则是子进程的 pid

执行结果如下图

Test2

将上述代码稍微修改一下

for(int i = 0; i<2; i++)
{
if(fork() == 0)
printf("A");
else
printf("B");
}

该循环中打印没有字符 "\n",无法刷新缓冲区

每一次 fork() 会复制之前进程中缓冲区的字符

最后执行结果为

BBBAABAA

(取决于两个进程执行的顺序)

Test3

if(fork() && fork())
printf("A\n");
else
printf("B\n");

该 if 块中第一个 fork() 生成一个子进程,返回 0,所以第二个 fork() 不会执行

父进程返回 pid,执行第二个 fork(),再次产生一个子进程

所以最终 printf 调用了三次,最后执行结果为

A
B
B

Test4

#include <stdio.h>
#include <stdlib.h> // 测试栈空间的变量
void f0()
{
int tmp = 0;
int pid = fork();
if(pid == 0)
{
tmp++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
} printf("%d\n",tmp);
} int tmp1 = 5;
// 测试全局变量
void f1()
{
int pid = fork();
if(pid == 0)
{
tmp1++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
} printf("%d\n",tmp1);
} // 测试堆区变量
void f2()
{
int *tmp2 = (int*)malloc(sizeof(int));
*tmp2 = 0;
int pid = fork();
if(pid == 0)
{
(*tmp2)++;
printf("son\n");
}
else if(pid > 0)
{
printf("parents\n");
}
else
{
return;
} printf("%d\n",*tmp2);
}

通过在 main 分别执行以上三个函数,输出中父进程与子进程打印的 tmp 值均不相同

可以发现,fork() 后生成新的子进程与父进程是相互独立的,拥有独立的 VMA

Linux -- 进程管理之 fork() 函数的更多相关文章

  1. 进程管理之fork函数

    fork函数的定义 #include <unistd.h> #include <sys/types.h> pid_t fork(void); fork函数在父进程中返回子进程的 ...

  2. UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习

    lienhua342014-10-07 在“进程控制三部曲”中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork ...

  3. 【Linux编程】进程标识符与fork函数

    ID为0的进程一般是调度进程.常被称为交换进程(swapper),是内核中的系统进程. ID为1的进程叫做init进程,是一个普通用户进程,不属于内核,由内核调用. 一个现有进程能够调用fork函数创 ...

  4. Linux进程管理知识整理

    Linux进程管理知识整理 1.进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些? TASK_RUNNING(可运行状态) ...

  5. Linux性能及调优指南(翻译)之Linux进程管理

    本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.1节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...

  6. Linux进程管理 (1)进程的诞生

    专题:Linux进程管理专题 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 L ...

  7. Linux进程管理 (2)CFS调度器

    关键词: 目录: Linux进程管理 (1)进程的诞生 Linux进程管理 (2)CFS调度器 Linux进程管理 (3)SMP负载均衡 Linux进程管理 (4)HMP调度器 Linux进程管理 ( ...

  8. 《Linux 性能及调优指南》1.1 Linux进程管理

    https://blog.csdn.net/ljianhui/article/details/46718835 本文为IBM RedBook的Linux Performanceand Tuning G ...

  9. 《Linux性能及调优指南》----1.1 Linux进程管理

    翻译:飞哥 ( http://hi.baidu.com/imlidapeng ) 版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明. 原文名称:<Linux Performance ...

随机推荐

  1. Creator 2.2.0 终于等来了这款Shader组件神器!一招搞定Effect特效

    先看下视频演示: ShaderHelper2支持Creator 2.2.0 视频录完后才想起,还没在微信小游戏中测试,赶紧试试,下面是在微信开发者工具中的截图. 径向模糊 探照灯 提供了一个Shade ...

  2. SpringCloud之Zuul配置问题

    当通过网关去调用服务的时候,尤其是服务里面配置了熔断,会发现拿不到熔断返回的信息 hystrix: command: default: execution: isolation: thread: ti ...

  3. srync:@ERROR: auth failed on module tee 的解决办法分析

    首先:检查server端和client端的用户名和密码确认都无误: 然后:检查了服务器端/etc/rsyncd.conf 配置文件未发现异常, 再次:通过配置文件找到了log存放目录 $ cat /e ...

  4. Linux Cannot allocate memory问题

    查找了一下相关文档,发现这个错误的含义其实就是像它自己说的,没法分配内存了. The problem is inherent with the way Java allocates memory wh ...

  5. vue之页面缓存问题(基于2.0)

    为什么会有这篇文章 在vue2.0中出现了列表页面是每次都重新加载数据,但是详情页面却只在第一次加载的时候调用数据,如果返回到列表再进入详情那么页面是不会重新渲染页面. 1 用vue-router 重 ...

  6. (Java) byte[] 和 base64 字符串之间的转换

    import org.apache.commons.codec.binary.Base64; public class UtilHelper { //base64字符串转byte[] public s ...

  7. token和session

    什么是token? token是服务端生成的一串字符串,目的是作为客户端进行请求的一个令牌.当第一次登录后,服务器生成一个token(一串字符串),并将此token返回给客户端,此后页面接收到请求后, ...

  8. Python监控SQL Server数据库服务器磁盘使用情况

    本篇博客总结一下Python采集SQL Server数据库服务器的磁盘使用信息,其实这里也是根据需求不断推进演化的一个历程,我们监控服务器的磁盘走了大概这样一个历程: 1:使用SQL Server作业 ...

  9. nginx篇最初级用法之SSL虚拟主机

    注意:在源码安装nginx时必须要使用--with-http_ssl_module参数启动加密模块. openssl genrsa > cert.key  //使用openssl自己签发私钥 o ...

  10. net core WebApi——April.Util更新之权限

    目录 前言 权限 中间层 小结 前言 在之前已经提到过,公用类库Util已经开源,目的一是为了简化开发的工作量,毕竟有些常规的功能类库重复率还是挺高的,二是为了一起探讨学习软件开发,用的人越多问题也就 ...