Bash 的 no-fork 优化
我们知道,Bash 在执行一个外部命令时,会先 fork() 一个子进程,然后在子进程里面执行 execve() 去加载那个外部程序。fork 子进程是会耗性能的,所以 Bash 会在下面几种情况下不 fork 子进程,直接在当前进程执行 execve()。
bash -c 'command'
如果用了 bash -c 的形式启动 Bash,同时 -c 选项的参数里只包含一个命令,比如 bash -c 'sleep 666',这时 Bash 不会 fork 子进程去运行 sleep 命令,它会让 sleep 直接占用自己现有的进程:
$ bash -c 'sleep 666' & $ pstree -ap ... | `-bash,3117 | |-pstree,3119 -ap | `-sleep,3118 666 ... |
3117 是我当前敲入命令的交互 Shell,3118 就是 bash -c 启动的那个进程,然后直接被替换成了 sleep,pid 还是 3118。
我们可以看一下 Bash 无法优化的情况下,进程树是什么样的:
$ bash -c 'sleep 666;ls' & $ pstree -ap ... | `-bash,3117 | |-bash,3120 -c sleep\040666;ls | | `-sleep,3121 666 | `-pstree,3122 -ap ... |
这次我们给 -c 的参数包含了两个命令,sleep 和 ls,所以 Bash 不能让 sleep 占用它的进程,因为执行完 sleep 它还得去执行 ls。
bash -c 'command1 && command2 || command3 ... && commandN'
在这种由若干个 && 和 || 把若干个简单命令组成的的复合命令中,最右侧的那个(commandN)命令执行时(如果执行到的话)会进行 no-fork 优化:
$ bash -c 'sleep 1 || sleep 2 && sleep 666' & $ pstree -ap # 等 3 秒钟后再执行这条 ... | `-bash,3117 | |-pstree,3126 -ap | `-sleep,3123 666 ... |
在 bash -c 'sleep 1 || sleep 2 && sleep 666' 这条命令中,一共产生过 3 个进程,bash -c 首先产生了一个进程 3123,然后 3123 又分别 fork 出两个子进程 3124 和 3125 来分别执行 sleep 1 和 sleep 2,sleep 666 没有产生新的进程,它和 bash -c 用了同一个进程,也就是 3123。这个优化在 Bash 4.4 之前没有。
( command )
用显示的子 shell 语法运行一个单独的命令,比如 ( sleep 100 ),如果不进行优化的话,这里应该先 fork 一个子 shell,然后这个子 shell 会再 fork 一个子子 shell 去运行 sleep,一共 fork 两次,再极端点:( ( ( ( ( sleep 100 ) ) ) ) ),会产生一个 5 级的子 shell(( ( ( ( ( echo $BASH_SUBSHELL ) ) ) ) ) 的确会输出 5),一共 fork 6次,然而 Bash 并不会这样做,无论你嵌套了多少级,Bash 只会 fork 一次,只产生一个子进程,然后在这个进程里执行 sleep 命令。
Bash 的 no-fork 优化的更多相关文章
- fork炸弹
众所周知,bash是一款极其强大的shell,提供了强大的交互与编程功能.这样的一款shell中自然不会缺少“函数”这个元素来帮助程序进行 模块化的高效开发与管理.于是产生了由于其特殊的特性,bash ...
- Bash 的若干基本问题
Bash 的若干基本问题 这里介绍一些bash启动前.后的问题,以及一些使用bash需要注意的基本问题. 1.Bash的介绍 Bash是一种Shell程序,它是一般的Linux系统中的 ...
- Linux基础优化与安全归纳总结
一名运维工程师在运维岗位上时间久了,就会发现Linux优化的重要性,同时会给运维工作带来很多的便利性.本人逐渐认识到了这一点,所以特意在工作闲暇之余,通过阅读Linux相关书籍及向同事.同行高手咨询, ...
- 总结linux内核的一些参数优化
sysctl命令被用于在动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中. 它包含一些TCP/IP堆栈和虚拟内存系统的高级选项, 用sysctl可以读取设置超过五百个系统变量. sy ...
- linux进程管理(上)
程序和进程的区别: 1.程序是一种静态资源 程序启动产生进程 2.程序与进程无一一对应原则 进程是动态的一个过程 父进程和子进程在前面提过 前台进程:执行命令时只能等待的进程为前台进程也叫异步进程 ...
- Ubuntu检测磁盘是否挂载
Ubuntu默认不自动挂载磁盘. 只是学习Bash使用,需优化如使用 # file: mountAll.sh # include color support # a list of variables ...
- 实现mypwd和mybash
一.pwd 1.学习pwd命令 man pwd查看pwd功能 可以得知pwd功能是打印当前目录 2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码 (1)man -k direc ...
- Linux 用户身份与进程权限
在学习 Linux 系统权限相关的主题时,我们首先关注的基本都是文件的 ugo 权限.ugo 权限信息是文件的属性,它指明了用户与文件之间的关系.但是真正操作文件的却是进程,也就是说用户所拥有的文件访 ...
- Linux进程的原理及与信号的联系
第1节 程序.进程.守护进程.僵尸进程的区别 程序.进程.守护进程.僵尸进程: 程序:c/php/java,代码文件,静态的,放在磁盘里的数据. 进程:正在内存中运行的程序,进程是动态的,会申请和使用 ...
随机推荐
- Linux配置本地无密码访问
本机配置无密码访问基本操作步骤: 1.ssh-keygen (效果同ssh-keygen -t rsa 一样,也可以ssh-keygen -t dsa) 2.ssh-copy-id -i ~/.ssh ...
- [转]ArcIMS 中地图坐标参考设置(ArcGIS Unknown Spatial Reference)
"ArcGIS Unknown Spatial Reference"问题: shp文件在Arcgis打开后经常因为原有坐标系无法识别而丢失信息,出现以下提示信息: "Un ...
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- Hibernate入门
脏检查及刷新缓存机制: 脏检查:当事物提交时,Hibernate会对session中持久状态的对象进行检测, 判断对象的数据是否发生改变 为什么要进行脏检查? 如果对象发生了改变,就需要将改变更新到数 ...
- Struts2 JQuery UI常用插件
一.什么是插件 ①是遵循一定接口规范编写的程序 ②是原有系统平台功能的扩展和补充 ③只能运行在规定的系统平台下,而不能单独运行 注:由于jQuery插件是基于jQuery脚本库的扩展,所以所有jQue ...
- 在MySQL中出现Unknown column 'abc' in 'field list'怎么解决?
update TABLE1 set NAME = '?' where ID ='?' 参数字段需要添引号.
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 基于数据库资源的多语言实现
以前的开发平台里,是用xml语言包实现了多语言功能,现在新的平台里进行了调整,把多语言包资源放在数据库表里实现了. 我们系统预留了多语言的配置全局变量.可以通过配置这个参数达到切换多语言的目的 我们在 ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 远程同步服务器大量基础数据到客户端
服务器上保存有上万条的基础数据,需要同步到全国各地的成千上万个客户端,而且这些基础数据也经常在有变化调整.这时候需要有一个稳定的数据同步程序,能分批同步基础数据,由于网络流量,网络的稳定性等因素,需要 ...
- 为普通Object添加类似AttachedProperty的属性
为普通Object添加类似AttachedProperty的属性 周银辉 我们知道,在WPF中对应一个DependencyObject,我们很容易通过AttachedProperty来为类型附加一 ...
- caffe的python接口学习(8):caffemodel中的参数及特征的抽取
如果用公式 y=f(wx+b) 来表示整个运算过程的话,那么w和b就是我们需要训练的东西,w称为权值,在cnn中也可以叫做卷积核(filter),b是偏置项.f是激活函数,有sigmoid.relu ...