看下小姐姐,舒缓下心情先。


好,现在回到我们的主题,看下下面这段代码,你觉得它会输出几个#号呢?

这个问题来自于我们技术群里的一位同学的提问,为了给大家一个思考时间,我们先不说结果,先再看下另一位可爱的小妹妹。


啊,好可爱啊,为啥我选择了技术,而没去学画画


好,不知道你想得怎么样了呢?

我们先来执行下,看下其具体输出。

看到没,8个,不知道你有没有猜对呢?

可为什么是8个呢,你要说2个我能理解,3个我也能理解,为什么偏偏是这么夸张的8个

其实这道题目主要考察两个点,第一个点就是fork的作用,如果你不理解fork,那你肯定认为输出的个数就是2个。

fork的作用其实就是拷贝当前进程,然后创建一个原样的子进程,子进程开始时执行的代码,就是父进程调用fork之后的代码。

对于我们上面的题目来说,子进程就是进入了下一次for循环。

详细的fork文档可以参考下面的链接:

https://man7.org/linux/man-pages/man2/fork.2.html

因为fork函数创建子进程,进而也会有#号输出,把这个考虑在内的话应该是3个#号,因为主进程会输出2个,主进程第一次for循环创建的子进程,在其进入到下一次循环时又会输出一个。

其他的因为主进程,或者是该子进程调用fork方法,创建的进一步的子进程再进入到for循环时,因为不满足 i < 2,会直接跳出循环,也就是说不会再输出#号。

那这样说也应该是3个#号啊,为什么是8个呢?

这里就涉及到了第二个知识点,printf。

为了减少系统调用次数,提高程序性能,我们每次调用printf时,并不会立即触发一次系统调用,而是会先写到printf的buffer区,如果buffer区满了,或者说写入字符中有\n换行符,才会真正的触发一次系统调用,将我们buffer中的printf的内容输出到控制台。

这也是有时我们写程序时,经常会发现明明调用了输出方法,但控制台上就是没有输出的一个常见原因。

好,再次回到我们的题目。

由上图我们可以看到,我们在for循环里调用的printf,都是没有加上\n换行符的,我们只有在进程结束前的printf才加上,也就是说,for循环里的printf,只是把我们的内容放到了它的buffer中,并没有真正输出。

那有意思的事就来了。

当我们后面再调用fork时,fork可是拷贝当前进程的全部内存的,这可是包括printf的buffer区的,举例来说,当我们主进程执行第二次for循环,调用fork时,此时的printf的buffer里已经有两个#号了,此时fork一个子进程,子进程中的相应buffer区里也会有这两个#号。

当主进程或子进程退出之前,遇到最后一个带有\n换行符的printf时,就会把buffer中现有的那两个#号输出出来,即每一个进程都会因为同样的原因,最终输出2个#号。

再看下我们的代码,算上主进程,一共创建了4个进程,那最终输出的可不就是8个#号嘛。

小知识,大学问!

不知道你有没有猜中这样的结尾呢?


写文章不易,如果可以的话,欢迎大家转发或给个在看,没关注的也可以关注下,希望以后能给大家带来更多的惊艳文章。

jq执行2次同样的方法怎么让第一次执行的不触发_他们说,这段代码你能看得懂她的开始,却猜不中她的结尾。...相关推荐

  1. jq执行2次同样的方法怎么让第一次执行的不触发_你不知道的CMS GC

    在G1出来之前,CMS绝对是OLTP系统的标配.即使G1出来几年了,生产环境很多的JVM实例还是采用ParNew+CMS的组合.但是即使其得到这么广泛的应用,还是有很多同学对它有很深的误解.本文主要对 ...

  2. JavaScript 自执行函数和 jQuery扩展方法

    我们通常将JS代码写在一个单独的JS文件中,然后在页面中引入该文件.但是,有时候引入后会碰到变量名或函数名与其它JS代码冲突的问题.那么如何解决这个问题呢?作用域隔离.在JS中,作用域是通过函数来划分 ...

  3. shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决

    shiro和Spring整合使用注解时没有执行realm的doGetAuthorizationInfo回调方法的解决 from :http://blog.csdn.net/babys/article/ ...

  4. 关于JQuery中的ajax请求或者post请求的回调方法中的操作执行或者变量修改没反映的问题...

    前段时间做一个项目,而项目中所有的请求都要用jquery 中的ajax请求或者post请求,但是开始处理一些简单操作还好,但是自己写了一些验证就出现问题了,比如表单提交的时候,要验证帐号的唯一性,所以 ...

  5. python子进程通信_python执行子进程实现进程间通信的方法

    本文实例讲述了python执行子进程实现进程间通信的方法.分享给大家供大家参考.具体实现方法如下: a.py: import subprocess, time subproc = subprocess ...

  6. layui表单提交使用form.on(‘submit(sub)‘,function (){}) 使用ajax请求时回调不执行的原因及解决方法

    layui表单提交使用form.on('submit(sub)',function (){}) 使用ajax请求时回调不执行的原因及解决方法 参考文章: (1)layui表单提交使用form.on(' ...

  7. python源程序执行的方式是什么执行-python调用可执行文件的方法

    最近要用到python调用C程序,因此,看了一下python调用别的程序的方法.大致来说,python调用C/C++有两种方式,一种是调用C编译的动态链接库,即so文件,一种是调用C生成的可执行文件. ...

  8. python 命令-Python中执行系统命令的四种方法

    一.os.system方法 在子终端运行系统命令,可以获取命令执行后的返回信息以及执行返回的状态.执行后返回两行结果,第一行是结果, 第二行是执行状态信息,如果命令成功执行,这条语句返回0,否则返回1 ...

  9. python自带的shell是什么-python中执行shell的两种方法总结

    一.使用python内置commands模块执行shell commands对Python的os.popen()进行了封装,使用SHELL命令字符串作为其参数,返回命令的结果数据以及命令执行的状态: ...

最新文章

  1. 帝国时代三计算机丢失,修复安装帝国时代程序出错3d3dx9_25.dll丢失在win7中方法...
  2. 【周末阅读】工业互联网的发展历程及实现路径
  3. 企业网络推广有效收录一定会带来排名?企业网络推广专员怎么说?
  4. python爬虫详细步骤-Python爬虫入门,详细讲解爬虫过程
  5. Winpcap进行抓包,分析数据包结构并统计IP流量
  6. 【STM32】FreeRTOS任务相关API
  7. Linux内核的启动过程分析
  8. 自然语言处理实践Task6
  9. 漏洞检测方法如何选?详解源代码与二进制SCA检测原理
  10. Linux下coredump调试3:补录
  11. LNMP架构介绍与搭建
  12. Hessian 3.2.0的两个bug(转)
  13. JS 实现两表格里的数据来回 转移
  14. 小程序二维码生成器在线制作_在线二维码生成器怎么挑?
  15. 追随你心 —— 聊聊VMCloud
  16. c语言程序设计题题库,c语言程序设计试题题库含答案
  17. 打印显示服务器脱机win10,如何在Win10中将打印机状态从脱机更改为联机
  18. python 滚动字幕_python – 在PyQt中滚动文本?
  19. MCGS 根据时间实现动态密码进行登陆
  20. 编程之美 - 孟岩点评

热门文章

  1. 13.2. Mount partition
  2. 个人信息安全 不能止于“打补丁”
  3. [转]12款最佳Linux命令行终端工具
  4. Renascence架构原理——遗传规划算法
  5. 关于angular的$resource中的isArray属性问题
  6. 水星三维引擎发布2.0版本 ~友情帮介绍下~
  7. ccna设备的NAT地址转换
  8. 《编程之美》读书笔记08:2.9 Fibonacci序列
  9. Tomcat的manager APP设置
  10. webservice服务器端获取request对象的三种方式