我们一起来学Shell - shell的并发及并发控制

简介: 我们一起来学Shell - shell的并发及并发控制

bash的并发

默认的情况下,Shell脚本中的命令是串行执行的,必须等到前一条命令执行完后才执行接下来的命令,但是如果我有一大批的的命令需要执行,而且互相又没有影响的情况下(有影响的话就比较复杂了),那么就要使用命令的并发执行了。

未使用并发的脚本

这个脚本是从etc var dev usr opt home这几个目录下找文件

使用time sh study.sh可以看到,执行这个脚本,需要用到0m4.297s

#!/usr/bin/env bash
arry=(etc var dev usr opt home)
for (( i=0; i<${#arry[@]}; i++ ))
do
    find /${arry[i]}/ -type f  >& /dev/null
done
echo "complate"

简单修改

使用time sh study.sh可以看到,执行这个脚本,只需要用到0m0.003s

#!/usr/bin/env bash
arry=(etc var dev usr opt home)
for (( i=0; i<${#arry[@]}; i++ ))
do
{
    find /${arry[i]}/ -type f  >& /dev/null
} &
done
echo "complate"

这样的话,循环里面的命令是作为后台进程在执行,主进程就不需要等待前面的命令执行完毕后,才执行后面的命令

如果上下两个命令是有依赖关系的,会得到错误的结果,因为上面的命令还没执行完成,就已经开始执行下面的命令了

使用wait命令

使用time sh study.sh可以看到,执行这个脚本,需要用到0m0.492s

#!/usr/bin/env bash
arry=(etc var dev usr opt home)
for (( i=0; i<${#arry[@]}; i++ ))
do
{
    find /${arry[i]}/ -type f  >& /dev/null
} &
done
wait
echo "complate"

因为使用了wait,要等循环内的命令执行结束了,才会执行后面的命令,因为虚拟机里面文件比较少,所以测试不出并发的差距,甚至因为使用了wait,导致时间比不并发的时间还要多一丢丢

但是如果数据量很大的话,就需要控制并发进程的个数,以免影响到系统的其他进程运行,导致系统宕机

控制并发进程的数量

以下脚本是利用文件描述符号和命名管道实现多进程并发控制,控制并发数量为5

以下脚本会创建254个用户,并且ping这个网段254次

使用time sh study.sh可以看到,执行这个脚本,需要用到1m8.744s

有兴趣的,可以尝试一下不开启并发,或者不开启并发控制

#!/usr/bin/env bash
ip="192.168.100."
use="test"
# 定义并发数量
thread=5
# 以当前进程 pid 创建 fifo 文件,防止冲突
tmp_fifofile=/tmp/$$.fifo
mkfifo ${tmp_fifofile}
# 定义当前进程打开管道文件(手动指定打开的文件描述符为8)
exec 8<> ${tmp_fifofile}
# 删除管道文件(当前进程没有释放文件描述符8,不影响)
rm ${tmp_fifofile}
# 往管道文件(文件描述符8)里循环写入内容
for i in $(seq ${thread})
do
    # 给管道文件(文件描述符8)输入${thread}个回车
    #(写入任何记录都可以,内容不重要,添加${thread}条记录.重定向,追加都可以,管道文件内容不会被覆盖)
    echo >&8
done
for i in {1..254}
do
    # read -u 读取一次文件描述符的内容
    #(read 读取不到内容就停止,管道文件只能读取一次,限制读取${thread}次)
    read -u 8
    {
    useradd ${use}$i
    echo "111" | passwd --stdin ${use}$i &>/dev/null
    if [ $? -eq 0 ]; then
        echo "$use$i is created"
    fi
    ping -c1 -W1 $ip$i &>/dev/null
    if [ $? -eq 0 ]; then
        echo "$ip$i is up"
    else
        echo "$ip$i is down"
    fi
    # 给管道文件(描述符号8)写入一个回车(还会一条记录,内容随意)
    echo >&8
    } &
done
wait
exec 8<&-
echo "complate"
文件描述符
  • fd 进程打开的文件
查看当前进程打开的文件
ll /proc/$$/fd
自定义当前进程用描述符号操作文件
  • 手动定义文件描述符,只要没有被占用可以使用
  • 自定义用当前进程打开一个文件,描述符为6
exec 6<> /file
  • 自定义用当前进程关闭一个文件,描述符为6
exec 6<&-
管道
  • 匿名管道不能跨终端 (| 管道)
  • 命名管道
  • 创建命名管道文件(不是普通文件,管道内的文件只能读取一次,不会永久保存)
mkfifo /tmp/fifo1
  • 查看命名管道文件
cat /tmp/fifo1


目录
相关文章
|
8月前
|
Shell
shell中并发执行多个进程
shell中并发执行多个进程
814 4
|
Prometheus 监控 Cloud Native
文件比对shell脚本实战(多线程并发shell)
文件比对shell脚本实战(多线程并发shell)
117 0
|
存储 Shell Linux
实验 Linux Shell实现模拟多进程并发执行【操作系统】
实验 Linux Shell实现模拟多进程并发执行【操作系统】
266 0
|
运维 Shell
【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)
【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)
124 0
|
运维 Shell 数据安全/隐私保护
【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(一)
【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)
190 0
|
Shell Windows
shell实战案例-批量ping ip(多进程限制并发)
shell实战案例-批量ping ip(多进程限制并发)
456 0
|
Shell Linux
shell脚本多进程并发写法实例(高阶修炼)
shell脚本多进程并发写法实例(高阶修炼)
|
Shell
shell脚本并发控制详解
shell并发控制 1.文件描述符 File Descriptors (FD,文件描述符或文件句柄):进程使用文件描述符来管理打开的文件 查看当前进程的fd 确定以下三点 如何exec打开一个文件 ​ exec 3&lt;&gt; file1.txt 如何exec关闭一个文件(释放文件句柄) 如果没有释放句柄,文件删除后描述符依然还在 ​ exec 3&lt;&- 当一个文件FD未被释放,删除源文件也不会影响FD ​ rm -rf file1 ​ cp /proc/$$/3 file1
629 0
|
网络协议 Shell Perl
tcp并发数攻击防御shell 脚本
自定义并发数量,达到峰值脚本将异常IP禁止访问
309 0
|
网络协议 Shell
tcpdump 方式检测ip 网段 扫段 tcp并发数攻击防御shell 脚本
tcpdump 自定义抓包时间将信息存入文件, 以systemd 系统服务方式进行启动
617 0