Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15177467
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-05-03 10:54:09

一个Bash的综合教学实例[协同程序, eval, 关联数组]
作者:home_king
实现把并行拷贝到多个路径下的功能。
知识点:
1. 使用了"协同程序",是拷贝进程并行化
2. 使用eval来实现变量的"间接扩充"
3. 使用awk的关联数组来剔除"文件当前路径"以及"重复路径",以避免拷贝并行化可能引起的"系统颠簸"甚至"拷贝错误"
4. 使用了stat获取目录inode,以判定路径的唯一性(不同的路径名可能指向同一个物理路径,如~, /root, /root/Desktop/../,又如~user, /home/user)

代码:
#!/bin/sh
#
# mcp---Multiple copy with Co-Process
#
checkargs(){
        if [ $# -eq 0 ];then
                echo 'No arguments supplied!'
                return 1
        fi
        cpfile=$1
        if [ ! -f $cpfile ]; then
                echo 'Invaild file to copy!'
                return 1
        fi
        shift
        for tmparg in "$@"; do
                if [ ! -d $tmparg ];then
                        echo "There's at least one invalid directory"
                        return 1
                fi
        done
        argnums=($(echo $(stat -Lc %i $@) | awk -v inum=$(stat -c %i $PWD) '{for(i=1;i<=NF;i++){if($i == inum)continue;ldirs[$i]=i}} END{for(item in ldirs){print ldirs[item]}}'))
}

checkargs $@
[ $? -eq 0 ] || exit 1
shift

echo "Destination:"
for arg in "${argnums[@]}"; do
        eval echo '$'$arg
        eval cp -f $cpfile '$'$arg &
done
wait
echo ""
echo 'All done!'

就这个例子,我们来对比一下并行化与非并行化的效率:
该:

代码:
[root@home root]# time ./mcp-1.0 perl1 /tmp ~home_king /home/home_king/ ~ /root
Destination:
/home/home_king/
/tmp

All done!

real    0m0.110s
user    0m0.010s
sys     0m0.050s

该脚本的普通拷贝(非并行化)版本(去除&以及wait):

代码:
[root@home root]# time ./scp perl1 /tmp ~home_king /home/home_king/ ~ /root
Destination:
/home/home_king/
/tmp

All done!

real    0m0.099s
user    0m0.010s
sys     0m0.040s

可见,在单CPU的机器上,"协同程序"带来的效率提升较小,甚至会降低原有的效率!

引用《Learning the Bash 》的一段话来结尾:

粗略地说,可以以三种方式总结一个进程使用系统资源地特性:是否为CPU密集型的(即进行频繁的CPU计算),I/O密集型的(进行频繁的写磁盘)或交互式的(需要用户交互)。
--------quote-START----------
对两个或多个不同种类的进程,进程越多同时运行它们就越有好处。例如,在和一个长的,I/O操作频繁的查询同时运行时,一个数值统计计算的作业会很有效率。
另一方面,如果两个进程以类似方式使用资源,则同时运行它们比按次序运行它们效率差一些。原因是在该条件下,操作系统经常需要按时间片抢夺资源。
例如,如果两个进程都进行频繁的磁盘操作,操作系统会进入一个模式,在两个竞争的进程之间会不断地来回切换对磁盘的控制权。系统进行切换操作的时间至少会和它处理进程本身操作的时间一样长。该现象称为系统颠簸(thrashing),最严重时,会使系统处于一个虚拟停顿状态。系统颠簸是一个常见问题,系统管理员和操作系统设计者会花费很多时间试图使其最小化。
---------quote-END-----------
阅读(1831) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~