PSk*_*cik 12 shell ksh fork command-substitution optimization
给定的
cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))'
Run Code Online (Sandbox Code Playgroud)
贝壳往往需要制作 2 个叉子才能实现
strace-f(){ strace -f "$@" 2>&1; };
for sh in dash bash zsh ksh; do
printf "$sh\t" ; strace-f $sh -c "$cmd" |grep -e clone -e fork -c;
done
Run Code Online (Sandbox Code Playgroud)
除了ksh
英勇地使它没有分叉一次:
dash 2
bash 2
zsh 2
ksh 0
Run Code Online (Sandbox Code Playgroud)
它是如何做到的?
编辑:
下面是它如何随着一个管道的插入而下降:
cmd='fun(){ echo "$@"| echo "$@"; }; fun $(fun $(fun hi))'
Run Code Online (Sandbox Code Playgroud)
输出:
dash 11
bash 10
zsh 5
ksh 3
Run Code Online (Sandbox Code Playgroud)
sch*_*ily 13
Ksh93 做了很多工作来避免分叉。我不知道它是如何知道如何处理第一种情况的,因为 atruss
表明它只调用一个write(2)
具有最终结果的调用。
可能是 David 扫描了 macro.c 中的命令,知道他可以在内部处理“echo”。
我能说的是,我去年重写了《Bourne Shell》的解析器和解释器,主要是减少了fork的数量,用vfork()
调用代替了很多fork 。这使得 Bourne Shell 成为仅次于 ksh93 的第二快的 shell。您可能还想运行您的测试bosh
。
顺便说一句:ksh93 通常避免分叉。它实现了一个包含所有先前全局变量的结构,如果使用“全局”变量结构指针的不同实例调用它,这会使 shell 代码可重入。
每当有(cmd)
子shell时,ksh93 都会使用此方法。
这次重写的原因是David在他的笔记本电脑上使用的是Win-DOS,他不喜欢Cygwin的慢,所以他写了UWIN,直接在Win-DOS上使用ksh93。由于fork()
Win-DOS上没有,他需要找到一个新的解决方案......
归档时间: |
|
查看次数: |
611 次 |
最近记录: |