1.利用& 和wait 相结合

#!/bin/bash cmd = ['su - oradu8 -c "lsnrctl start"','su - du8adm -c startsap'] starttime=date +%s #开始运行时间 for t in {1..100} #for ((i=1; i<=100; i ++)) for i in seq 1 100   do   {   sleep 5 #sleep 模仿命令执行花费的时间   echo 'success'$i;   echo 'date +%s'   }& #将每次循环命令放入后台执行,放入后台,意味着{}里面的命令交给操作系统的一个线程处理 #循环了100次,就有100个&任务放入后台,操作系统会并发100个线程来处理这些任务   done   wait #wait命令的意思是,等上面放入后台命令都执行完毕了再继续。       #在这里写wait是因为,一条命令一旦被放入后台后,这条任务就交给了操作系统       #shell脚本会继续往下运行(也就是说:shell脚本里面一旦碰到&符号就只管把它       #前面的命令放入后台就算完成任务了,具体执行交给操作系统去做,脚本会继续       #往下执行),所以要在这个位置加上wait命令,等待操作系统执行完所有后台命令 endtime=date +%s #定义脚本运行的结束时间 echo "TIME:expr $end - $start"

  1. 利用管道的特性,不读则阻塞 #!/bin/bash start_time=date +%s #定义脚本运行的开始时间 [ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道 exec 5<>/tmp/fd1 #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性 rm -rf /tmp/fd1 #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了 for ((i=1;i<=10;i++)) do echo >&5 #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌" done

for i in {1...100} do read -u5 #代表从管道中读取一个令牌 { sleep 5 #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替) echo 'success'$i echo >&5 #代表我这一次命令执行到最后,把令牌放回管道 }& done wait

stop_time=date +%s #定义脚本运行的结束时间

echo "TIME:expr $stop_time - $start_time" exec 5<&- #关闭文件描述符的读 exec 5>&- #关闭文件描述符的写