一、函数fork

fork函数原型:

#include <unistd.h>
pid_t fork(void);

二、程序清单

1. 测试代码:

#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <iostream>
using namespace std;static int global_val = 0;
int main()
{int *p = (int*)malloc(sizeof(int));*p = 0;int m = 2;pid_t pid;int fd = open("mytest", O_RDWR | O_CREAT, 0666);if ((pid = fork()) < 0){cout << "fork error" << endl;}else {if (pid == 0){char buf[20] = "\0";int res = read(fd, buf, 20);cout << "pid is " << getpid() << " res is " << res << " fd is " << fd << " buf is " << buf << endl;close(fd);//sleep(1);char bufs[8] = "shenlei";lseek(fd, 0, SEEK_SET);write(fd, bufs, strlen(bufs));global_val++;m++;(*p)++;}else {sleep(1);char buf[20] = "\0";lseek(fd, 0, SEEK_SET);int res = read(fd, buf, 20);cout << "pid is " << getpid() << " res is " << res << " fd is " << fd << " buf is " << buf << endl;cout << *p << " " << m << " " << global_val << endl;}}return 0;
}
#include <stdio.h>
#include <unistd.h>int main()
{pid_t pid;for(int i = 0; i < 4; ++i)printf("--------i = %d\n", i);pid = fork();if(pid > 0) printf("parent process, pid = %d\n", getpid());else if(pid == 0)printf("child process, pid = %d, ppid = %d\n", getpid(), getppid());for(int i = 0; i < 4; ++i)printf("i = %d\n", i);return 0;
}

输出结果:

2. 测试代码:

#include <stdio.h>
#include <unistd.h>int counter = 200;
int main()
{int number = 5;int i;pid_t pid;for(i  = 0; i < number; ++i) {pid = fork();if(pid == 0) {break;}}if(i == 0){counter += 200;printf("first process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == 1){counter += 200;printf("second process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == 2){counter += 200;printf("thrid process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}if(i == number){sleep(3);counter += 400;printf("parent process, pid = %d\n", getpid());printf("-----couner = %d\n", counter);}return 0;
}

输出结果:

3. 测试代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>int main()
{int i;pid_t pid;printf("xxxxxxxxxxxxxxxxxxxxx\n");for(i = 0; i < 5; ++i) {pid = fork();if(pid == -1) {perror("fork error:");exit(1);} else if(pid == 0) {break;}}if(i < 5) {sleep(i);printf("I'am %d child, pid = %d\n", i+1, getpid());} else {sleep(i);printf("I'am parent\n");}return 0;
}

输出结果:

三、父子进程共享

父子进程之间在fork后,有哪些相同,有哪些相异之处呢?

刚fork之后:

父子相同处:全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主ID(家目录)、进程工作目录、信号处理方式
父子不同处:进程ID、fork返回值、父进程ID、进程运行时间、闹钟(定时器)、未决信号集

似乎,子进程复制了父进程0-3G用户空间内容,以及父进程的PCB、但pid不同,真的每fork一个进程都要将父进程完全程的0-3G地址空间完全拷贝一份,然后在映射至物理内存吗?

当然不是!父子进程间遵循读时共享写时复制的原则,这样设计,无论子进程执行父进程的逻辑还是执行自己的逻辑都能节省内存开销。

重点注意:躲避父子进程共享全局变量的知识误区!

【重点】:父子进程共享:1. 文件描述符(打开文件的结构体)  2. mmap建立的映射区

1. 测试代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>int var = 24;int main()
{pid_t pid;pid = fork();if(pid == -1) {perror("fork");exit(1);} else if(pid > 0) {var = 55;sleep(1);printf("I'am parent pid = %d, parent ID = %d, var = %d\n", getpid(), getppid(), var);} else if(pid == 0) {var = 100;printf("child pid = %d, parent ID = %d, var = %d\n", getpid(), getppid(), var);}printf(" var = %d\n", var);    return 0;
}

输出结果:

函数fork vfork相关推荐

  1. linux中fork()函数与vfork()函数的区别

    对于fork函数: 子进程只继承父进程的文件描述表,不继承但共享文件表项和i-node 父进程创建一个子进程之后,文件表项中的引用计数加1变为2,当父进程作close操作之后计数器减1,子进程还是可以 ...

  2. UNIX再学习 -- 函数 fork 和 vfork

    一.进程标识 每个进程都有一个非负整数形式的唯一编号,即 PID.PID 在任何时刻都是唯一的,但是可以重用,当进程终止并被回收以后,其 PID 就可以为其它进程所用.进程的 PID 由系统内核根据延 ...

  3. fork()函数与vfork()函数的区别

    1.fork()函数与vfork()函数 头文件: #include <sys/types.h> #include <unistd.h> 函数原型: pid_t fork(vo ...

  4. linux中fork函数与vfork函数的区别

    fork函数跟vfork函数一样能够创建进程,它们主要有两个区别 (1)区别一: vfork直接使用父进程存储空间,不拷贝. (2)区别二: vfork保证子进程先运行,当子进程调用exit退出后,父 ...

  5. 函数 —— fork()分叉函数

    阅读目录 fork()运行时做的事情 父子进程文件共享问题 fork()函数在底层中做了什么? vfork和fork的之间的比较: 记得以前初次接触fork()函数的时候,一直被"print ...

  6. fork vfork exit _exit (转)

    原文地址:http://hi.baidu.com/ikaruga11/blog/item/fb6d75725a8d8d148701b080.html APUE上的一个例子: example1 (for ...

  7. 【Linux进程、线程、任务调度】二 fork/vfork与写时拷贝 线程的本质 托孤 进程睡眠和等待队列

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2(已满): 780902027 学习 ...

  8. linux父进程中显示子进程pid,请教linux下c语言函数fork父进程打印子进程的PID

    请教linux下c语言函数fork父进程打印子进程的PID 关注:296  答案:2  信息版本:手机版 解决时间 2019-01-14 04:55 雨不眠的下 2019-01-13 12:23 用于 ...

  9. 进程创建函数fork()和vfork()

    Linux下使用fork()创建一个新的进程,该函数不需要参数,返回值是一个进程id.对于不同的对象,分别是:新建的子进程id(返回给父进程),0(返回给创建的子进程)或者-1(子进程创建失败,返回给 ...

最新文章

  1. 通信系统之信道(二)
  2. LeetCode686 Repeated String Match(字符串匹配)
  3. thinkphp通过模型查询mysql_thinkPHP视图模型详解,把mysql表关联简单化!
  4. NYOJ 716 River Crossing(动态规划)
  5. 西安交大计算机考研分数线2020院线,西安交通大学2020考研复试分数线已公布
  6. 支付分当钱花有人信了?微信辟谣:开通微信支付分不收费
  7. mysql 解决慢sql_MySQL被慢sql hang住了,用shell脚本快速清除不断增长的慢sql的办法...
  8. 抖音电商带货,卖给粉丝还是卖给有需要的人?
  9. 哈希(1) hash的基本知识回顾
  10. Flash MX游戏制作常用代码解析
  11. 智慧环卫系统建设方案(智能垃圾分类收运管理)
  12. 把 14 亿人拉到一个微信群,如何实现?
  13. php 多元数组,php数组_php多元数组
  14. Flutter仿京东商城项目实战视频教程
  15. 下载哔哩哔哩代码php,哔哩哔哩电脑客户端 v1.4.4 官方最新版
  16. linux gem安装软件,安装gem报错
  17. 论文-Interactive Path Reasoning on Graph for Conversational Recommendation
  18. DAY 2 Perceived and cognition || HTML CSS 入门
  19. wifidog源码分析 - 初始化阶段
  20. 大学计算机实验报告虚拟机,安装虚拟机的实验报告(共10篇).docx

热门文章

  1. C#在ASP.NET4.5框架下的首次网页应用
  2. Delphi运算符及优先级
  3. 网站后台中对html标签的处理
  4. 转载:glut.h 与 stdlib.h中 的exit()重定义问题的解决
  5. flash调用js中的方法,让js传递变量给flash (兼容 IE FF) (转)
  6. 写接口给别人调用 推送数据到我们_我们写了一个超好用的抖音矩阵数据管理工具...
  7. mysql权限表_MySQL 数据库赋予用户权限操作表
  8. java none怎么用tomcat_使用tomcat做java中间件
  9. Opencv——图像金字塔与图像尺寸缩放
  10. Python---寻找给定序列中相差最小的两个数字