子进程继承父进程缓冲区|学习笔记

简介: 快速学习子进程继承父进程缓冲区

开发者学堂课程【物联网开发- Linux 高级程序设计全套视频子进程继承父进程缓冲区 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/660/detail/10987


子进程继承父进程缓冲区

 

内容简介:

一、前言

二、代码实现及说明

三、检验是否继承

 

一、前言

看以下例子,此例子是验证什么?

以前讲过像 printf 等这些函数是带缓冲区的,其中以前提到过 openread 、 write 、 read 和 write ,是系统调用级的接口函数,但是 I/O 函数是不带缓冲区的,比如如果 write 文件里面写东西,它就立马会进入文件,它不会存到缓冲区里面,系统调用级的 I/O 函数是不带缓冲区的,然后这一个代码是验证了父进程如果有一个缓冲区的,且缓冲区里面有东西,它会继承给子进程,因为缓冲区就是一块内存,它是继承给子进程的。

 

二、代码实现及说明

1、输入例子中的代码

先看一下以下代码:

#include <stdio.h>

#include <stdlib,h>

#include <unistd.h>

#include <string.h>

int main(int argc, char *argv[])

{

pid_t pid;

int length = 0

char buf[] = “a write to stdout\n”;

length = write(1, but,strlen(buf));

if(length != strlen(buf));

{

printf(“write error\n”);

}

printf(“before fork\n”);

pid=fork();

if(pid<0)

{

perror(“fork”);

}

else if(pid==0)

{

printf(“in son process\n”);

}

else

{

sleep(1);

printf(“in father process\n”)

}

return 0;

}

2、点斜杠执行及相关说明

(1)说明及内容

注意创建进程时的一些特点,看以上代码,在这个程序当中它定义了一个字符数组,看 write 函数往哪写, fd 是1,1代表标准输出,往标准输出及屏幕上写 buffer 指向的字符串有很多个字节,把“a write to stdout\n”字符串写到标准输出设备软件及屏幕上去,然后当执行第11行的时候,屏幕上立马就又多了一个“a write to stdout\n”,然后判断如果出错的话如何处理,如果不出错它就继续往下执行。

注意 printf 是缓缓冲,因为缓冲区里面有反斜杠n,于是“ before fork ”这句话又到了屏幕上,假如这是咱们的屏幕,当运行程序的时候,在终端里已经打印了两句话了,然后接下来它 fork , fork 之后创建子进程,子进程直接去打 printf (“in son process\n”)这句话,而父进程先 sleep 挂起,所以肯定是“in son process”这一句话被打到屏幕上,这句话是子进程打入的,一秒钟之后,父进程再去打printf(“in father  process\n”)这句话,子进程再打完之后,Return 0结束了,父进程一秒钟之后打 in father 这句话,也结束了,所以如果点斜杠执行,

打印的就是以下这种效果:

a write to stdout

before fork

in son process

in father process

(2)运行结果及分析

①运行

先看一下此程序运行结果是不是想要的,格式转为 UTF8 无 BOM 格式,

执行结果如下:

[01_day]./fork2

in son process var=11,num=10

common code area

in father process var=10,num=9

common code area

[01_day]gcc fork3.c -o fork3

[01_day]./fork3

a write to stdout

before fork

in son process

in father process

②结果分析

和以上分析的一模一样,点斜杠执行的时候,它其实父进程的缓冲区里面是没东西的,因为父进程的缓冲区 printf 的时候被刷新了,有反斜杠 n ,而且要 write 的时候,它就是不带缓冲的。

3、去掉点斜杠n执行及相关说明

(1)说明及内容

现在改一下上述代码,拓展一下,如果把 before folk.\n 中的“./n”去掉,那它父进程 before folk 的时候, before folk 应该是在缓冲区里,然后到 folk 的时候,在父进程的缓冲区会打入 before folk ,接下来它没有刷新缓冲区在 printf 的时候,因为 printf是缓缓冲,它没有反斜杠 n 不刷新缓冲区,然后它就 folk ,这样的话缓冲区就被子进程继承了,注意子进程的缓冲区有 before folk ,父进程有个 before folk 在缓冲区里面,子进程当中也有,然后接下来它folk创建子进程了之后,在子进程当中打 printf(“in  son  process\n”),注意 in son process 这句话是 printf 的,首先它先打到缓冲区里边,因为有反斜杠 n ,所以它把缓冲区里全部刷新,刷新到屏幕上,

注意 a write to stdout还是要执行,父进程当中首先有这句话,注意第一个 before folk是谁刷到屏幕上的,是子进程刷到屏幕上的,然后过了一秒钟之后父进程打印 in father process 这句话, Printf 首先会把数据打到缓冲区里边,因为打印的时候有反斜杠 n ,所以它会刷新缓冲区,把父进程当中的缓冲区刷到屏幕上。

(2)运行结果及分析

①运行上述代码

这个程序的运行结果就变成这样:

a write to stdout

before fork

in son process

before fork

in father process

②对以上结果进行分析及改进

注意第一个 before folk 是子进程刷出来的,第二个 before folk和 in father process 是父进程刷出来的,因为把反斜杠 n 去掉了之后,就使得在创建子进程的时候,缓冲区里面是有东西继承了给子进程。将以上代码运行一下,看看第一次的时候是不是如分析的一样运行的,即只有一个 before folk ,

运行代码如下所示:

[01_day]./fork3

a write to stdout

before fork

in son process

③再次编译进行运行

然后再次编译,将反斜杠 n 去掉之后,运行代码如下所示:

[01_day]gcc fork3.c -o fork3

[01_day]./fork3

a write to stdout

before forkin son process

before forkin father process

④对以上结果分析及改进

所以当把反斜杠 n 去掉了之后,屏幕上应该是这种效果,before folk 后边没有反斜杠 n 了,效果如下:

a write to stdout

before forkin son process

before forkin father process

⑤再次编译进行运行

验证了子进程可以继承父进程的缓冲区,一会先写这个代码,写了这个代码之后再将反斜杠n去掉,看看效果是不是多了一个 before folk 。

4、带着反斜杠 n 运行

(1)说明及效果

其实还有一种运行方式,带着反斜杠 n 运行这个程序的时候,是以下这种效果:

[01_day]./fork3

a write to stdout

before fork

in son process

in father process

(2)对以上进行分析及改进

只有一个 before folk ,但是如果逆向的输入 aaa.txt ,什么意思?这个程序的输出到屏幕上的东西重逆向到文件里面去了,输出到普通文件里面去了,注意这时 printf 就由缓缓冲变成了全缓冲,也就是说在这种运行方式下,在执行 printf 的时候,即便是有反斜杠 n ,它也不刷新缓冲区了,因为它已经不是缓缓冲了,它变成了全缓冲,因为缓缓冲是碰到反斜杠n才刷新缓冲区,而全缓冲碰到反斜杠 n 它也不刷新,那么什么时候刷新?

当缓冲区满了、程序结束了、或者是人为的刷新缓冲区,所以这种情况也能将 before folk 继承给子进程,因为有反斜杠n它也不刷新缓冲区。

 

三、检验是否继承

看看能不能继承,先输入以下代码:

[01_day]./fork3 > aaa.txt

[01_day]vi aaa.txt

执行结果如下:

a write to stdout

before fork

in son process

before fork

in father process

可以看到有两个 before folk ,其中“before fork in son process”

是子进程刷进来的,“before forkin father process”是父进程刷进来的,那么这两个代码用了两种方式,改了一种方式,另外一种方式运行的时候重合了,然后验证了子进程可以继承父进程的缓冲区。

相关文章
|
4月前
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
6月前
|
小程序 Linux
【编程小实验】利用Linux fork()与文件I/O:父进程与子进程协同实现高效cp命令(前半文件与后半文件并行复制)
这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作
136 2
|
7月前
|
JavaScript 前端开发 Shell
深入Node.js的进程与子进程:从文档到实践
深入Node.js的进程与子进程:从文档到实践
有 3 个进程 P1、P2、P3 协作解决文件打印问题。P1 将文件记录从磁盘读入内存的缓冲区 1,每执行一次读一个记录 ;P2 将缓冲区 1 中的内容复制到缓冲区 2 中,每执行一次复制一个记录 ;
有 3 个进程 P1、P2、P3 协作解决文件打印问题。P1 将文件记录从磁盘读入内存的缓冲区 1,每执行一次读一个记录 ;P2 将缓冲区 1 中的内容复制到缓冲区 2 中,每执行一次复制一个记录 ;
|
7月前
|
机器学习/深度学习
3 个进程 P1、P2、P3 互斥地使用一个包含 N(N > 0)个单元的缓冲区。P1 每次用 produce() 生成一个正整数,并用 put() 将其送入缓冲区的某一空单元中 ;P2每次用 get
3 个进程 P1、P2、P3 互斥地使用一个包含 N(N > 0)个单元的缓冲区。P1 每次用 produce() 生成一个正整数,并用 put() 将其送入缓冲区的某一空单元中 ;P2每次用 get
让“父进程”可以有自己的工作,不需要因为为了“子进程”回收资源而堵塞。但也要满足“子进程”退出后的资源能被立马回收。(不能使用任何的进程通信机制 比如:信号等)
让“父进程”可以有自己的工作,不需要因为为了“子进程”回收资源而堵塞。但也要满足“子进程”退出后的资源能被立马回收。(不能使用任何的进程通信机制 比如:信号等)
|
8月前
|
存储 Linux
【linux进程控制(二)】进程等待--父进程是如何等待子进程死亡的?
【linux进程控制(二)】进程等待--父进程是如何等待子进程死亡的?
|
8月前
|
Unix Linux C语言
【进程OI】重定向的本质&&用户级缓冲区
【进程OI】重定向的本质&&用户级缓冲区
|
8月前
|
算法 Linux Shell
【linux进程(二)】如何创建子进程?--fork函数深度剖析
【linux进程(二)】如何创建子进程?--fork函数深度剖析
|
8月前
|
Linux Shell
【Linux】进程与可执行程序的关系&&fork创建子进程&&写实拷贝的理解
【Linux】进程与可执行程序的关系&&fork创建子进程&&写实拷贝的理解

相关实验场景

更多