[Chapter 3 Process]Practice 3.1 相关知识:进程创建、fork函数
3.1 Using the program shown in the Figure3.30, explain what the output will be at LINE A

答案:LINE A 处的输出是PARENT: value = 5。
解析: 此问题的相关知识有进程创建、fork函数。
当父进程调用fork函数时, 新创建的子进程几乎但不完全与父进程相同, 子进程会获得一份父进程用户级虚拟地址空间的拷贝, 但是此拷贝是独立的, 拷贝内容包括文本、数据和bss段、堆以及用户栈。
所以在图中程序执行时, 子进程有一份自己的虚拟地址空间, 里面存放着和父进程相同的一份代码、数据、用户栈的拷贝, 而且是与父进程的地址空间是独立的。 因此, 子进程和父进程都有一个value变量, 二者互不影响。程序执行时, 子进程中的value会改变为20, 但是父进程的value值依然是5.
扩展: 在父进程创建新的子进程时, 子进程还会获得与父进程打开文件描述符相同的拷贝, 也就是说, 当父进程调用fork函数时, 子进程可以读写父进程中打开的任何文件。 父进程和子进程之间的最大区别在于它们有不同的PID。
fork函数是有趣的(也是常常令人迷惑的), 因为它只被调用一次, 却会返回两次: 一次是在调用进程(父进程)中返回, 返回值是新建的子进程的PID; 一次是在新建的子进程中返回, 返回值是0。 因此总是可以利用fork的返回值来判断程序是在父进程还是子进程中执行。
#include <sys/types.h>
#include<unistd.h>
pid_t fork(void);
返回: 子进程返回0, 父进程返回子进程的PID, 如果出错, 则为-1。
如果是第一次学习fork函数, 画进程图通常会有所帮助, 其中每个水平的箭头对应与从左到右执行指令的进程, 而每个垂直的箭头对应于fork函数的执行。


下面的图示是一个父进程创建子进程的实例

当在Linux系统上运行这个程序时, 我们得到下面的结果:
parent: x = 0
child : x = 2
这个简单的例子有一些微妙的方面。
*调用一次, 返回两次。 对于只创建一个子进程来说, 这还是挺直接的, 但是具有多个fork实例的程序可能会令人迷惑。
*并发执行。 父进程和子进程是并发运行的独立进程。 内核能够以任意方式交替执行他们的逻辑控制流中的指令。在此系统上运行这个程序时, 父进程先完成它的printf语句, 然后是子进程。 然而, 在另一个系统上可能正好相反。 一般而言, 作为程序员, 决不能对不同进程中指令的交替执行做出任何假设。
*相同的但是独立的地址空间。 如果能够在fork函数在父进程和子进程中返回后立即暂停这两个进程, 我们会看到每个进程的地址空间都是相同的。 每个进程的有相同的用户栈、 相同的本地变量值、相同的堆、相同的全局变量值, 以及相同的代码。 因此, 在实例程序中, 当fork在第8行返回时, 本地变量x在父进程和子进程都为1. 然而因为父进程和子进程都是独立的进程, 它们都有自己的私有地址空间。 父进程和子进程对x所做的任何改变都是独立的, 不会反映在另一个进程的存储器中。 这就是为什么当父进程和子进程调用各自的printf语句时, 它们中的变量x会有不同的值的原因。 3.1问题同样是这个原因。
*共享文件。 当运行这个实例程序时, 我们注意到父进程和子进程都把它们的输出显示到了屏幕上。 原因就是子进程继承了父进程所有打开的文件。 当父进程调用fork函数时, stdout文件是被打开的, 并指向屏幕。 所以子进程的输出也指向了屏幕。
文章中的理论知识摘自《Computer Systems: A Programmer's Perspective second edition》
[Chapter 3 Process]Practice 3.1 相关知识:进程创建、fork函数的更多相关文章
- [Chapter 3 Process]Practice 3.2 Including the initial parent process, how many processes are created by the program shown in Figure?
3.2 Including the initial parent process, how many processes are created by the program shown in Fig ...
- [Chapter 3 Process]Practice 3.12 Including the initial parent process, how many processes are created by the program shown in Figure 3.32?
3.12 Including the initial parent process, how many processes are created by the program shown in Fi ...
- [Chapter 3 Process]Practice 3.5 When a process creates a new process using the fork() operation
3.5 When a process creates a new process using the fork() operation, which of the following state is ...
- [Chapter 3 Process]Practice 3.3 Discuss three major complications that concurrent processing adds to an operating system.
3.3 Original version of Apple's mobile iOS operating system provied no means of concurrent processi ...
- [Chapter 3 Process]Practice 3.9 Describe the actions token by a kernel to content-switch between processes.
3.9 Describe the actions token by a kernel to content-switch between processes. 答案: 内核在进行进程上下文切换时, 首 ...
- [Chapter 3 Process]Practice 3.8: Describe the differences among short-term, medium-term, long-term scheduling
3.8 Describe the differences among short-term, medium-term, and longterm scheduling. 答案: 长期调度决定哪些进程进 ...
- [Chapter 3 Process]Practice 3.4 Describe what happens when a context switch occurs if the new context is already loaded into one of the register sets.
3.4 The Sun UltraSPARC processor has multiple register sets. Describe what happens when a context sw ...
- python的面向对象-实例(对象)的相关知识、实例化
1.对象就是实例,什么是实例 类运行的过程就是实例化的过程,实例化产生的结果就是产生了一个实例 class的牛逼之处就是不用手动的return,他会加载完函数之后,自动return __init__ ...
- 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸
类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...
随机推荐
- 如何检查BioPerl是否正确安装
如果是Linux系统,随意打开一个终端:如果用的是Windows系统,那么打开命令提示符. 输入以下命令: perldoc Bio::SeqIO 以上命令的作用是查看Bio::SeqIO模块的文档是否 ...
- QT QStringListModel 示例代码
1. QStringListModel , 实现 插入 删除 编辑 list,支持鼠标双击编辑. 2. dialog.h #ifndef DIALOG_H #define DIALOG_H #inc ...
- 机器学习之K-近邻(KNN)算法
一 . K-近邻算法(KNN)概述 最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类.但是怎么可能所有测试对象都会找到 ...
- Spring Boot入门——全局异常处理
1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dependency> <groupId>org.springfr ...
- review37
线程的常用方法 1.start() 线程调用该方法将启动线程,使之从新建状态进入就绪队列排队. 2.run() 3.sleep() 4.isAlive() 线程处于新建状态时,线程调用isAlive( ...
- Linux软件安装(一)
软件安装方式: 1. rpm方式 该方式软件安装本质与Windows下安装软件方式一致,就是把软件包里面的二进制代码文件复制到系统指定目录(如 C://program files) 优点:软件安装非常 ...
- ADO.NET入门教程(一) 初识ADO.NET
摘要 作为.NET框架最重要的组件之一,ADO.NET扮演着应用程序与数据交互的重要的角色.本文将从宏观的角度来探讨ADO.NET,和大家一起了解ADO.NET来龙去脉以及ADO.NET的主要组成部分 ...
- c# 打开第三方软件(如:电脑自带看图软件)
嘿嘿,直接上示例代码 /// <summary> /// 利用第三方软件浏览加工图纸 /// </summary> /// <param name="fileP ...
- JS将数字转换成三位逗号分隔的样式
function formatNum(num) { if(!/^(\+|-)?(\d+)(\.\d+)?$/.test(num)){alert("wrong!"); return ...
- android 关于Toast重复显示解决方法
解决思路: 不用计算Toast的时间之类的,就是定义一个全局的成员变量Toast, 这个Toast不为null的时候才去make,否则直接setText.为了按返回键后立即使Toast不再显示,重 ...