命名管道Shell并发线程控制

题目:写一个脚本,判断192.168.182.0/24网络里,当前在线的IP有哪些,能ping通则认为在线。

原始代码如下:
#!/bin/bash
for i in `seq 255`
do
       ping -c 1 192.168.182.$i>>/dev/null 2>&1
       [ $? -eq 0 ] && echo "192.168.182.$i在线"
       
done

这个脚本使用一个线程阻塞执行了255次循环,每次循环执行一秒,扫描完需要用255s,效率是十分低的。

改进如下:
#!/bin/bash
for i in `seq 255`
do
       { ping -c 1 192.168.182.$i>>/dev/null 2>&1
       [ $? -eq 0 ] && echo "192.168.182.$i在线"
       }&
done
wait

用{}把循环体括起来,后加一个&符号,代表每次循环都把命令放入后台运行,系统会分配一个线程给这个循环,这样就会同时产生255个线程同时执行。

如果脚本下面还有内容就需要wait等待后台命令执行完毕再继续往下执行。

wait命令的意思是,等待(wait命令)上面的命令(放入后台的)都执行完毕了再往下执行。因为,一条命令一旦被放入后台后,这条任务就交给了操作系统,shell脚本会继续往下运行(也就是说:shell脚本里面一旦碰到&符号就只管把它前面的命令放入后台就算完成任务了,具体执行交给操作系统去做,脚本会继续往下执行),所以要在这个位置加上wait命令,等待操作系统执行完所有后台命令。

使用Linux管道文件特性制作队列,控制线程数目

有名管道特性:

mkfifo pip 创建命名管道

1.cat < pip(阻塞并等待数据输入管道)
在这里插入图片描述
2.echo ‘abc’ > pip(如果没有读管道的操作,则阻塞)

在这里插入图片描述
在这里插入图片描述
可以理解成必须在同一时间有读管道的操作和写管道的操作,管道中的数据才能从一个进程转移到另一个进程,利用命名管道的上述特性就可以实现一个队列控制了,管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,但是问题是当往管道文件里面放入一个资源,没人取则会阻塞,这样你永远也没办法往管道里面同时放入10段内容,解决这个问题的关键就是文件描述符了。

exec 3<>pip,创建文件描述符3关联管道文件,这时候3这个文件描述符就拥有了管道的所有特性,还具有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,而不用关心管道内是否为空,也不用关心是否有内容写入引用文件描述符, &3可以执行n次echo >&3 往管道里放入n个资源。

代码:

#!/bin/bash

start_time=`date +%s` #定义脚本运行的开始时间
[ -e pip ] || mkfifo pip
exec 3<>pip         #定义文件描述符3,以读写方式打开pip文件
rm -rf pip			#描述符3拥有pip的全部功能,命名管道文件可以删除
for j in `seq 30`	
do
        echo>&3			#引用30次文件描述符3,往管道里面放入了30个资源
done
for i in `seq 255`
do
        read -u3		#从管道中读取一个资源并执行下面的语句
{
        ping -c 1 192.168.182.$i>>/dev/null 2>&1
        [ $? -eq 0 ] && echo "192.168.182.$i在线"
        echo >&3			#每执行完一次放回一个资源
}&
done
wait
stop_time=`date +%s` #定义脚本运行的结束时间
echo “TIME:`expr $stop_time - $start_time`”
exec 3<&-				#关闭文件描述符的读
exec 3>&-				#关闭文件描述符的读

在这里插入图片描述
两个for循环,第一个for循环30次,相当于向管道中放入了30个资源,

第二个for循环255次,read -u3相当于占用一个资源,{}里面最后一行代码echo >&3相当于一次循环执行结束,将资源归还。

注意:创建一个文件描述符exec 3<>pip 不能有空格,代表文件描述符3有可读(<)可写(>)权限,注意,打开的时候可以写在一起,关闭的时候必须分开关,exec 3<&-关闭读,exec 3>&-关闭写。

理解的还不够透彻,先做个记录。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值