Linux下使用fork()创建一个新的进程,该函数不需要参数,返回值是一个进程id。对于不同的对象,分别是:新建的子进程id(返回给父进程),0(返回给创建的子进程)或者-1(子进程创建失败,返回给父进程)。创建的新进程在得到一个新的进程id之后,将拷贝父进程空间中内容至子进程,包括父进程的数据段和堆栈段,并且子进程和父进程共享代码段。vfork()和fork()则不一样,父子进程共享地址空间,包括代码段、数据段和堆栈段。子进程对于共享数据的修稿会影响到父进程,而且子进程一定比父进程先运行完,父进程调用vfork()函数后等待子进程运行完成再接着运行。

接下来,使用fork()创建一个子进程,并且在子进程中显示父进程的进程号和子进程的进程id,在父进程中显示出父进程的进程id和子进程的进程id。

#include<iostream>
#include<stdlib.h>
#include<unistd.h>
using namespace std;int main(){pid_t pid;pid = fork();if(pid < 0){cout << "Create fail!" << endl;exit(0);}else if(pid == 0){cout << "This is the child process! PID is: " << getpid() << endl;cout << "The parent process id is: " << getppid() << endl;}else{cout << "This is the parent process! PID is: " << getpid() << endl;cout << "The child process id is: " << pid << endl;}return 0;
}

编译并运行:

发现在子进程中,由函数getppid()返回的进程号与对应的父进程的进程号并不一致。在父进程中,能够正确返回子进程的进程id。利用ps命令查看子进程返回的父进程id对应的进程:upstart,后来在博客https://blog.csdn.net/Leafage_M/article/ details/70273624中看到一个很清楚详细的解释。shell中先打印出父进程的进程信息,然后再打印出子进程的进程信息,那么就相当于父进程完成之后,被杀死了,然后再执行的是子进程的信息,而此时子进程就成了孤儿进程,它被upstart这个进程收养了,此时调用getppid()返回的当然就是upstart的pid了。对于这种问题的解决方法之一就是在父进程的执行语句中加入延时挂起sleep()操作,让父进程不至于太快销毁。

之前说到fork()和vfork()的区别,编写两个实例进行验证:

#include<iostream>
#include<stdlib.h>
#include<unistd.h>
using namespace std;int global; //全局变量(数据段中)
int main(){pid_t pid;int stack = 1;  //局部变量(栈中)int* heap;  //局部变量(堆中)heap = (int* )malloc(sizeof(int));*heap = 2;pid = fork();if(pid < 0){cout << "Fail to fork!" << endl;exit(1);}else if(pid == 0){global ++;stack ++;(*heap)++;cout << "This is the child process! PID is: " << getpid() << endl;cout << "The parent process id is: " << getppid() << endl;cout << "The child data: " << global << " " << stack << " " <<  *heap << endl;exit(0);}else{   sleep(3);  cout << "This is the parent process! PID is: " << getpid() << endl;cout << "The child process id is: " << pid << endl;cout << "The parent data: " << global << " " << stack << " " << *heap << endl;exit(0);}return 0;
}

之后再将上面程序中fork()函数改为vfork(),并将延时语句注释掉。编译和运行结果对比:

可以看出,fork()创建的子进程中三个变量都发生变化时,父进程虽然在子进程之后才访问数据,但是子进程中对变量的修改并不影响父进程的进程环境。但是vfork()则不一样。再看进程id,在加入sleep()函数之后,fork()函数创建的子进程也能够正常返回父进程的id了。而在vfork()函数创建的子进程中,父子进程的返回的父进程、子进程id皆一致。

fork()函数在两种情况下容易出错:系统中已经有很多进程,调用fork()函数的用户进程过多。

进程创建函数fork()和vfork()相关推荐

  1. Linux中的进程创建函数fork

    为什么80%的码农都做不了架构师?>>>    Linux中的进程通过fork创建,并通过exec执行,分为两步. 在Linux中所有的进程都是pid为1的init进程的子进程,内核 ...

  2. Linux进程的创建函数fork()及其fork内核实现解析

    进程的创建之fork() Linux系统下,进程可以调用fork函数来创建新的进程.调用进程为父进程,被创建的进程为子进程. fork函数的接口定义如下: #include <unistd.h& ...

  3. Linux系统编程之进程控制(进程创建,fork函数,进程中止,进程等待,程序替换)

    进程创建 fork()------复制,返回值,写时复制 vfork()创建子进程-子进程与父进程共用同一块虚拟地址空间, 为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出或者进行程序 ...

  4. c语言fork函数fpid初始值,进程创建,fork()函数讲解

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

  5. 关于 Linux fork()进程创建函数 的 执行方式 返回值 lockf锁和并发 控制创建顺序 的探索

    文章目录 BEGIN Demo 1 - 了解fork执行方式 code & result comprehension Demo 2 - fork的返回值研究 code & result ...

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

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

  7. 小何讲进程: Linux进程控制编程 (fork、vfork)

    所谓进程控制,就是系统使用一些具有特定功能的程序段来创建进程.撤消进程以及完成进程在各种状态之间的转换, 从而达到多进程高效率并发执行和协调资源共享的目的.进程控制是进程管理和处理机管理的一个重要任务 ...

  8. linux创建进程读共享写复制,Linux进程创建之fork浅析

    在Linux 内核中,无时无刻不维护着进程,从进程的创建到进程销毁,每一个环境都有着复杂的细节.本篇介绍Linux 内核如何创建进程,深入理解 fork 函数以及子进程的创建,对理解多进程开发也至关重 ...

  9. 函数简介篇——进程创建函数:system()

    说明:   本文章旨在总结备份.方便以后查询,由于是个人总结,如有不对,欢迎指正:另外,内容大部分来自网络.书籍.和各类手册,如若侵权请告知,马上删帖致歉.   QQ 群 号:513683159 [相 ...

最新文章

  1. 浅谈代码的执行效率(1):算法是关键
  2. 2020年网易校招提前批JAVA岗笔试第一题
  3. OpenCASCADE:Mac OS X平台使用Xcode构建OCCT
  4. Ext.js4.x 的面板中嵌入UEditor编辑器
  5. 学习的回顾--数组的有关内容
  6. R语言转换并保存json文件--使用jsonlite包
  7. 轻松决绝疑难杂症:nodejs使用http报错: Request path contains unescaped characters
  8. 教你如何将中文转换成全拼
  9. win7工作组无法查看计算机名,win7系统无法查看工作组计算机怎么解决
  10. tftp64工具使用
  11. matlab——度分秒与度的转换
  12. qq android 哪个版本好用吗,Android QQ轻聊版好用吗?
  13. word自动生成目录,设置从指定页码开始
  14. 2012最犀利语录大全
  15. Shadowing Japanese Unit 5
  16. 查看对方使用什么手机型号
  17. C语言中printf打出2进制与16进制数
  18. MPI实现并行pagerank
  19. android和asp交互,Android客户端用Json与Asp.Net服务器交互信息
  20. 武汉微软认证考点及考试流程 与 微软认证考试流程

热门文章

  1. CUDA运行时 Runtime(四)
  2. YOLOV4各个创新功能模块技术分析(二)
  3. 2021年大数据Spark(三十二):SparkSQL的External DataSource
  4. Python:数据集成
  5. Java的类,对象以及字段和方法
  6. 常用 Git 命令清单
  7. Python os模块常用命令
  8. 中国互联网+固体饮料行业商业模式创新与投资机会深度研究报告
  9. nodejs文件上传报错总结
  10. 【转】Flask安装