linux shell编程多线程和wait命令学习

Shell中并没有真正意义的多线程,要实现多线程可以启动多个后端进程,最大程度利用cpu性能。

直接看代码示例吧。

(1) 顺序执行的代码

#!/bin/bash
date
for i in `seq 1 5`
do
{
    echo "sleep 5"
    sleep 5
}
done
date

输出:

Sat Nov 19 09:21:51 CST 2016
sleep 5
sleep 5
sleep 5
sleep 5
sleep 5
Sat Nov 19 09:22:16 CST 2016

(2) 并行代码

使用’&’+wait 实现“多进程”实现

在执行命令后加&操作符,表示将命令放在子shell中异步执行。可以达到多线程效果。

wait [作业指示或进程号]
1.等待作业号或者进程号制定的进程退出,返回最后一个作业或进程的退出状态状态。如果没有制定参数,则等待所有子进程的退出,其退出状态为0.
2.如果是shell中等待使用wait,则不会等待调用函数中子任务。在函数中使用wait,则只等待函数中启动的后台子任务。
3.在shell中使用wait命令,相当于高级语言里的多线程同步。
例子:
1.使用wait等待所有子任务结束。

#!/bin/bash 
sleep 10 #等待10秒,再继续下一操作
sleep 10 & #当前shell不等待,后台子shell等待
#!/bin/bash
sleep 10 &
sleep 5&
wait $! #$!表示上个子进程的进程号,wait等待一个子进程,等待5秒后,退出

2.在函数中使用wait

#!/bin/bash
source ~/.bashrc


fun(){
    echo "fun is begin.timeNum:$timeNum"
    local timeNum=$1
    sleep $timeNum &
    wait #这个只等待wait前面sleep

    echo "fun is end.timeNum:$timeNum"
}


fun 10 &
fun 20 &


wait #如果fun里面没有wait,则整个脚本立刻退出,不会等待fun里面的sleep
echo "all is ending"

输出结果为:

fun is begin.timeNum:10
fun is begin.timeNum:20
fun is end.timeNum:10
fun is end.timeNum:20
all is ending
#!/bin/bash
date
for i in `seq 1 5`
do
{
    echo "sleep 5"
    sleep 5
} &
done
wait  ##等待所有子后台进程结束
date

输出:

Sat Nov 19 09:25:07 CST 2016
sleep 5
sleep 5
sleep 5
sleep 5
sleep 5
Sat Nov 19 09:25:12 CST 2016

(3) 对于大量处理任务如何实现启动后台进程的数量可控?

  简单的方法可以使用2层for/while循环实现,每次wait内层循环的多个后台程序执行完成。

  但是这种方式的问题是,如果内层循环有“慢节点”可能导致整个任务的执行执行时间长。

  更高级的实现可以看(4)

(4) 使用命名管道(fifo)实现每次启动后台进程数量可控。

#!/bin/bash


function my_cmd(){
    t=$RANDOM
    t=$[t%15]
    sleep $t
    echo "sleep $t s"
}


tmp_fifofile="/tmp/$$.fifo" 
mkfifo $tmp_fifofile      # 新建一个fifo类型的文件
exec 6<>$tmp_fifofile     # 将fd6指向fifo类型
rm $tmp_fifofile    #删也可以


thread_num=5  # 最大可同时执行线程数量
job_num=100   # 任务总数


#根据线程总数量设置令牌个数
for ((i=0;i<${thread_num};i++));do
    echo
done >&6 


for ((i=0;i<${job_num};i++));do # 任务数量
    # 一个read -u6命令执行一次,就从fd6中减去一个回车符,然后向下执行,
    # fd6中没有回车符的时候,就停在这了,从而实现了线程数量控制
    read -u6 


    #可以把具体的需要执行的命令封装成一个函数
    {   
        my_cmd
    } &


    echo >&6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
done


wait
exec 6>&- # 关闭fd6
echo "over"

转载:http://www.cnblogs.com/xudong-bupt/p/6079849.html`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值