博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
fork() || fork()和fork() && fork()笔试题
阅读量:4251 次
发布时间:2019-05-26

本文共 2909 字,大约阅读时间需要 9 分钟。

程序一:

int main()  {          fork() || fork();          printf("+");          return 0;  }

结果输出3个”+”,共创建3个进程。

fork()给子进程返回一个零值,而给父进程返回一个非零值;

在main这个主进程中,首先执行 fork() || fork(), 左边的fork()返回一个非零值,根据||的短路原则,前面的表达式为真时,后面的表达式不执行,故包含main的这个主进程创建了一个子进程,

由于子进程会复制父进程,而且子进程会根据其返回值继续执行,就是说,在子进程中, fork() ||fork()这条语句左边表达式的返回值是0, 所以||右边的表达式要执行,这时在子进程中又创建了一个进程,

即main进程->子进程->子进程,一共创建了3个进程。

程序二:

int main()  {          fork() && fork();          printf("+");          return 0;  }

结果输出3个”+”,共创建3个进程。

程序三:

int main()  {          fork() || fork() || fork();          printf("+");          return 0;  }

结果输出4个”+”,共创建4个进程。

程序四:

int main()  {          fork() && fork() && fork();          printf("+");          return 0;  }

结果输出4个”+”,共创建4个进程。

程序五:

int main()  {          fork() || fork() || fork() || fork();          printf("+");          return 0;  }

结果输出5个”+”,共创建5个进程。

程序六:

int main()  {          fork() && fork() && fork() && fork();          printf("+");          return 0;  }

结果输出5个”+”,共创建5个进程。


一、fork入门知识

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

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

我们来看一个例子:

#include 
#include
int main () { pid_t fpid; //fpid表示fork函数返回的值 int count=0; fpid=fork(); if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am the child process, my process id is %d/n",getpid()); printf("我是爹的儿子/n");//对某些人来说中文看着更直白。 count++; } else { printf("i am the parent process, my process id is %d/n",getpid()); printf("我是孩子他爹/n"); count++; } printf("统计结果是: %d/n",count); return 0; }

运行结果是:

i am the child process, my process id is 5574我是爹的儿子统计结果是: 1i am the parent process, my process id is 5573我是孩子他爹统计结果是: 1

在语句fpid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的几乎完全相同,将要执行的下一条语句都是if(fpid<0)……

为什么两个进程的fpid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

  • 在父进程中,fork返回新创建子进程的进程ID;
  • 在子进程中,fork返回0 ;
  • 如果出现错误,fork返回一个负值;

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

引用一位网友的话来解释fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.

fork出错可能有两种原因:

1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。

2)系统内存不足,这时errno的值被设置为ENOMEM。

创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

每个进程都有一个独特(互不相同)的进程标识符(process ID),可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值。

fork执行完毕后,出现两个进程,

有人说两个进程的内容完全一样啊,怎么打印的结果不一样啊,那是因为判断条件的原因,上面列举的只是进程的代码和指令,还有变量啊。

执行完fork后,进程1的变量为count=0,fpid!=0(父进程)。进程2的变量为count=0,fpid=0(子进程),这两个进程的变量都是独立的,存在不同的地址中,不是共用的,这点要注意。可以说,我们就是通过fpid来识别和操作父子进程的。

还有人可能疑惑为什么不是从#include处开始复制代码的,这是因为fork是把进程当前的情况拷贝一份,执行fork时,进程已经执行完了int count=0;fork只拷贝下一个要执行的代码到新的进程。

二、fork进阶知识

三、fork高阶知识

请看博客地址:

转载地址:http://ocuei.baihongyu.com/

你可能感兴趣的文章
Dijkstra算法--一个点到其余点最短路径
查看>>
解决 The `master` repo requires CocoaPods 1.0.0 - (currently using 0.39.0)
查看>>
gdb调试常用命令
查看>>
vim正则表达式批量修改文本
查看>>
objective-c init方法的写法
查看>>
极客公园 Mac 第三方客户端(swift)
查看>>
【Lintcode】寻找峰值
查看>>
Arduino 串口读写 SD 卡模块
查看>>
图的基本算法--深度优先搜索(dfs) 和 广度优先搜索(bfs)
查看>>
[Linux] Linux内核编译安装过程,及Linux源码目录结构
查看>>
[Linux] c语言变量的存储位置-笔记
查看>>
[Linux] 头文件实质-笔记
查看>>
统一修改iOS中xib颜色值
查看>>
数据湖与数据仓库的新未来:阿里提出湖仓一体架构
查看>>
基于 Flink+Iceberg 构建企业级实时数据湖 | 附 PPT 下载
查看>>
Flink 源码:Checkpoint 元数据详解
查看>>
基于Flink+ClickHouse打造轻量级点击流实时数仓
查看>>
Flink sink schema 字段设计小技巧
查看>>
Flink 使用 union 代替 join 和 cogroup
查看>>
踩坑记 | Flink 天级别窗口中存在的时区问题
查看>>