fork函数的作用

在Linux中fork函数是非常重要的函数,它的作用是从已经存在的进程中创建一个子进程,而原进程称为父进程。

调用fork(),当控制转移到内核中的fork代码后,内核开始做:

1.分配新的内存块和内核数据结构给子进程。

2.将父进程部分数据结构内容拷贝至子进程。

3.将子进程添加到系统进程列表。

4.fork返回开始调度器,调度。

来段代码:

1#include《stdio.h》

2#include《unistd.h》

3#include《stdlib.h》

4intmain()

5{

6pid_tpid;

7printf(“before:pidis%d\n”,getpid());

8if((pid=fork())==-1)

9perror(“fork()”),exit(1);

10printf(“After:pid=%d,forkreturn%d\n”,getpid(),pid);

11sleep(1);

12

13return0;

14}

15123456789101112131415

这个简单的例子有一些微妙的方面:

•调用一次,返回两次

fork函数被父进程调用一次,但是却返回两次;一次是返回到父进程,一次是返回到新创建的子进程。

•并发执行

子进程和父进程是并发运行的独立进程。内核能够以任意的方式交替执行他们的逻辑控制流中的指令。在我们的系统上运行这个程序时,父进程先运行它的printf语句,然后是子进程。

•相同但是独立的地址空间

因为父进程和子进程是独立的进程,他们都有自己私有的地址空间,当父进程或者子进程单独改变时,不会影响到彼此,类似于c++++的写实拷贝的形式自建一个副本。

•fork的返回值

1.fork的子进程返回为0;

2.父进程返回的是子进程的pid。

•fork的常规用法

1.一个父进程希望复制自己,使得子进程同时执行不同的代码段,例如:父进程等待客户端请求,生成一个子进程来等待请求处理。

2.一个进程要执行一个不同的程序。

•fokr调用失败的原因

1.系统中有太多进程

2.实际用户的进程数超过限制

fork函数创建进程

在linux下,C语言创建进程用fork函数,接下来我们通过代码来一步步了解fork函数的各个知识点。

1、依赖的头文件

1#include《unistd.h》

2、fork的原理和概念

fork子进程就是从父进程拷贝一个新的进程出来,子进程和父进程的进程ID不同,但用户数据一样。

在C语言中,创建一个子进程代码如下:

pid_tpid;//pid_t从底层来看,实际上是int类型。

pid=fork();

3、父进程和子进程

执行fork函数后有2种返回值:对于父进程,返回的是子进程的PID(即返回一个大于0的数字);对于子进程,则返回0,所以我们可以通过pid这个返回值来判断当前进程是父进程还是子进程。如下代码所示:

if(pid》0)

{

printf(“imparentprocess,pid:%d\n”,getpid());

}

elseif(pid==0)

{

printf(“imchildprocess,pid:%d,parentpid:%d\n”,getpid(),getppid());

}

else

{

printf(“forkfailed\n”);

}

温馨提示:

getpid()-获取当前进程的pid

getppid()-获取当前进程的父进程的pid

4、完整例子&子进程代码执行位置

了解这些之后,我们来看一个创建子进程的完整代码示例:

#include《stdio.h》

#include《unistd.h》

intmain(intargc,char*argv[])

{

printf(“==========beforefork=============\n”);

pid_tpid;

pid=fork();

printf(“==========afterfork=============\n”);

if(pid》0)

{

printf(“imparentprocess,pid:%d\n”,getpid());

}

elseif(pid==0)

{

printf(“imchildprocess,pid:%d,parentpid:%d\n”,getpid(),getppid());

}

else

{

printf(“forkfailed\n”);

}

printf(“==========processend=============\n”);

sleep(1);

return0;

}

运行结果如下图:

从上图可以看出,程序只输出了1个“beforefork”,但输出了2个“afterfork”,所以我们可以得出:子进程的代码执行是从fork()位置之后开始的。事实也确实是如此。

5、循环创建子进程

有时候,我们需要创建多个子进程,可以通过for循环来实现,代码如下:

#include《stdio.h》

#include《unistd.h》

intmain(intargc,char*argv[])

{

inTI=0;

pid_tpid;

for(i=0;i《3;i++)

{

pid=fork();

}

if(pid==0)

{

printf(“imchildprocess,pid:%d,parentpid:%d\n”,getpid(),getppid());

}

else

{

printf(“imparentprocess,pid:%d\n”,getpid());

}

sleep(1);

return0;

}

运行结果如下图:

咦,我们不是循环创建3个子进程吗,怎么输出了这么多次parentprocess和childprocess呢?

这是因为子进程也创建了子进程,大家可以观察一下图中的pid。数了一下,共输出了8次,刚好是2的3次方。

我画了一个fork步骤图,便于大家更好的理解,如下:

如上图所示,子进程在第2轮、3轮,也会相当于父进程一样继续fork子进程,所以for循环3次后,刚好得到共8个进程。

那如果我们就想通过循环3次,得到3个子进程,要怎么办呢?

思路:不让子进程fork出新的子进程。

代码片段如下:

for(i=0;i《3;i++)

{

pid=fork();

if(pid==0)

{

break;

}

}

运行结果:

至此,fork函数创建子进程介绍完毕。

责任编辑:YYX

c++中的fork函数_fork函数的作用_fork函数创建进程相关推荐

  1. python函数对变量的作用_python函数对变量的作用及遵循的原则

    1.全局变量和局部变量 全局变量:指在函数之外定义的变量,一般没有缩进,在程序执行的全过程有效 局部变量:指在函数内部使用的变量,仅在函数内部有效,当函数退出时变量将不存在 例如: 1 n=1 #n是 ...

  2. python函数对变量的作用_python函数局部变量用法

    当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的.这称为变量的 作用域 .所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开 ...

  3. python process 函数_Python Process创建进程的2种方法详解

    前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...

  4. linux main是什么进程,从创建进程到进入main函数,发生了什么?

    从创建进程到进入main函数,发生了什么? 从创建进程到进入main函数,发生了什么? 前几天,读者群里有小伙伴提问:从进程创建后,到底是怎么进入我写的main函数的? 今天这篇文章就来聊聊这个话题. ...

  5. c++中的fork函数_fork函数

    复刻(fork,又译作派生.分支)是UNIX或类UNIX中的分叉函数,fork函数将运行着的程序分为2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程.这两个进程中的线程继续 ...

  6. c++中的fork函数_fork( )函数详解

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

  7. linux中的fork函数详解

    在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程.在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID.我们可以通过fork返回的值来 ...

  8. c++中的fork函数_linux c语言 fork() 和 exec 函数的简介和用法

    linux c语言 fork() 和 exec 函数的简介和用法 假如我们在编写1个c程序时想调用1个shell脚本或者执行1段 bash shell命令, 应该如何实现呢? 其实在<stdli ...

  9. c++中的fork函数_Linux C/C++——fork()函数基础

    一.定义 1.fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程.创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令.子 ...

  10. Linux中的fork()和clone()函数

    原文地址:https://blog.csdn.net/qq_42837885/article/details/101950162 fork函数 在linux中fork函数是非常重要的函数,它从已存在进 ...

最新文章

  1. 深入理解 wpa_supplicant(四)
  2. postgresql 9.1 暂停 stream 后使用 rsync 异机同步文件
  3. C语言树形打印二叉树
  4. RHCE课程-RH131Linux管理笔记五-Linux远程登陆telnet及ssh服务
  5. 【数据挖掘知识点六】假设检验
  6. Cheatsheet: 2010 04.26 ~ 04.30
  7. JVM 学习三:类加载器
  8. linux学习134 unit6
  9. java 解析p12_java读取*.p12证书的信息 | 学步园
  10. Illustrator 教程,如何在 Illustrator 中创建及应用图案?
  11. 一键拼接所有微信好友头像
  12. sym4 matlab,使用MATLAB工具wfusimg函数进行图像的融合
  13. 关于 error: invalid types ‘int[int]‘ for array subscript 的解决
  14. c语言复杂万年历带农历,c语言实现农历万年历(48页)-原创力文档
  15. Java狐仙ol,狐仙八大职业介绍 简要分为四类
  16. @Value注解获取不到配置值
  17. oracle自动加一天,如何将Oracle 当前日期加一天、一分钟
  18. Excel:多个单元格内容合并——“”-PHONETIC()函数-Text()函数
  19. c++ abs 取绝对值函数
  20. HDU 2212 DFS (伪·DFS)

热门文章

  1. .gen地图文件的投影编程实现(以墨卡托投影和兰伯特投影为例)
  2. 如何学习财务数据分析,有哪些好工具?
  3. python与工程造价的联系_终于知道工程造价专业面试技巧
  4. MOSSE 相关滤波器详解
  5. Linux面试题(总结最全面的面试题!!!)
  6. 内网穿透工具,微信支付支付宝支付的沙箱接口回调地址
  7. 代码走查和代码审查_代码审查是个好主意的其他原因
  8. 北大计算机专业毕业论文,北京大学毕业论文格式范本
  9. community_louvain社群划分方法
  10. 蓝牙AVRCP协议解析