精华内容
下载资源
问答
  • 2020-12-05 10:15:50

    1、怎么理解shell并发:

    当我们在执行一个for循环时,假设这个for循环需要循环500次,每循环一次就需要1秒,当这个for循环的脚本执行完毕时,就需要500秒,这样看效率有些低(尤其在量级高的时候,会更明显),所以我们需要shell脚本的for循环无论循环多少次,让它们同时执行,不需要按顺序循环,这就是shell脚本的并发。

    2、如何实现shell脚本并发:

    实现非常简单,就是在循环体的{}后面加上一个&符号,代表每次循环体的命令都放入后台运行

    3、经典实例:

    判断192.168.80.0/24网络,当前在线的主机数以及IP

    #!/bin/bash
    . /etc/init.d/functions
    cmd="ping -c 2"
    for ((i=1;i<=254;i++));do
    {
    	$cmd 192.168.80.$i &>/dev/null
    	if [ $? = 0  ];then
    	action "192.168.80.$i"  /bin/true
    	fi
    }&		#将{}循环体放入后台执行
    done
    wait		#等待上面放入后台的命令执行完毕后,在往下执行(如果后面还有要执行的命令,最好加上wait),因为命令一旦放到后台执行,这条任务就交个操作系统了,shell脚本会不等上面的执行完毕,就会继续往下执行。
    

    扩展知识点:

    我们知道了什么是shell脚本的并发,试想一下,如果此时有1000个任务并发,就会有1000个线程产生,如果系统的资源跟不上,就会让计算机系统产生很大的压力,导致操作系统处理的速度会越来越慢。而此时我们又当如何解决呢?出现这个情况时,我们可以引入命名管道文件来处理。
    命名管道处理的思路:
    就相当于此时有10个开水房间,配有10把钥匙,此时有100个人要打开水,那么前10个人抢到钥匙,就先进去打开水,后面的90个人就需要等前面一个人出来后还回钥匙,在拿着钥匙进去打开水,这样就能控制100个人打开水的任务,同时不会将系统的资源一次性耗用太多,增加压力,减小处理速度。
    知识点:
    1、命名管道的特性
    如果管道内容为空,则阻塞
    管道具有读一个少一个,存一个读一个的性质,放回去的可以重复取
    可以实现队列控制
    如果管道放一段内容没有人取,则会阻塞
    解决上述问题,可以通过文件描述符
    文件描述符具有管道的所有特性,同时还具有一个管道不具有的特性:无限存不阻塞,无限取不阻塞,无需关注管道内容
    创建方式:
    1、创建命名管道

    mkfifo  /tmp/fl
    

    2、创建文件描述符100,并关联到管道文件

    exec 100<>/tmp/fl   
    

    3、调用文件描述符,向管道里存放内容,同时也表示将用完的管道内容在放回管道

    echo >&100   
    

    4、读取文件描述符关联管道中的内容

    read -u100
    

    5、关闭文件描述符的读和写

    exec 100<&-
    exec 100>&-
    

    实例演示:引用上面的网络测试案例

    #!/bin/bash
    . /etc/init.d/functions
    cmd="ping -c 2"
    mkfifo /tmp/fl
    exec 100<>/tmp/fl
    rm -rf /tmp/fl
    for ((n=1;n<=100;n++));do
    	echo >&100
    done
    for ((i=1;i<=254;i++));do
    	read -u100
    {
    	$cmd 192.168.80.$i &>/dev/null
    	if [ $? = 0  ];then
    	echo "192.168.80.$i is ok" 
    	else
    	echo "192.168.80.$i is no"  
    	fi
    	echo >&100     #将管道内容在放回去
    }&
    done
    wait
    #echo "test compelet"
    exec 100<&-
    exec 100>&-
    
    更多相关内容
  • 需求:100个shell脚本任务,同时不超过20个并发执行,通过shell脚本实现。 使用linux管道文件特性制作队列,控制线程数目 知识储备: 一.管道文件 1:无名管道(ps aux | grep nginx) 2:有名管道(mkfifo /tmp/fd1)...

    需求:100个shell脚本任务,同时不超过20个并发执行,通过shell脚本实现。

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

    知识储备:

    一.管道文件

    1:无名管道(ps aux | grep nginx)

    2:有名管道(mkfifo /tmp/fd1)

    有名管道特性:
    1.cat /tmp/fd1(如果管道内容为空,则阻塞)

    实验:
    在这里插入图片描述
    2.echo “test” > /tmp/fd1(如果没有读管道的操作,则阻塞)
    二.文件描述符

    1.管道具有存一个读一个,读完一个就少一个,没有则阻塞,放回的可以重复取,这正是队列特性,但是问题是当往管道文件里面放入一段内容,没人取则会阻塞,这样你永远也没办法往管道里面同时放入10段内容(想当与10把药匙),解决这个问题的关键就是文件描述符了。

    1. mkfifo /tmp/fd1

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

    exec命令用法:exec命令用法

    实现:

    #!/bin/bash
    start_time=`date +%s`              #定义脚本运行的开始时间
    [ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道
    exec 3<>/tmp/fd1                   #创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
    rm -rf /tmp/fd1                    #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了
    for ((i=1;i<=10;i++))
    do
            echo >&3                   #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌"
    done
     
    for ((i=1;i<=1000;i++))
    do
    read -u3                           #代表从管道中读取一个令牌
    {
            sleep 1  #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替)
            echo 'success'$i       
            echo >&3                   #代表我这一次命令执行到最后,把令牌放回管道
    }&
    done
    wait
     
    stop_time=`date +%s`  #定义脚本运行的结束时间
     
    echo "TIME:`expr $stop_time - $start_time`"
    exec 3<&-                       #关闭文件描述符的读
    exec 3>&-                       #关闭文件描述符的写
    

    代码解析以及问题:

    两个for循环,第一个for循环10次,相当于在女士公共厕所门口放了10把钥匙,第二个for

    循环1000次,相当于1000个人来上厕所,read -u3相当于取走一把药匙,{}里面最后一行代码echo >&3相当于上完厕所送还药匙。

    这样就实现了10把药匙控制1000个任务的运行,运行时间为101s,肯定不如方案二快,但是比方案一已经快很多了,这就是队列控制同一时间只有最多10个线程的并发,既提高了效率,又实现了并发控制。

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

    展开全文
  • shell并发控制 1.文件描述符 File Descriptors (FD,文件描述符或文件句柄):进程使用文件描述符来管理打开的文件 查看当前进程的fd 确定以下三点 如何exec打开一个文件 ​ exec 3<> file1.txt 如何exec...

    shell并发控制

    1.文件描述符

    File Descriptors (FD,文件描述符或文件句柄):进程使用文件描述符来管理打开的文件

    查看当前进程的fd

    确定以下三点

    如何exec打开一个文件

    ​ exec 3<> file1.txt

    如何exec关闭一个文件(释放文件句柄)

    如果没有释放句柄,文件删除后描述符依然还在

    ​ exec 3<&-

    当一个文件FD未被释放,删除源文件也不会影响FD

    ​ rm -rf file1

    ​ cp /proc/$$/3 file1

    [root@localhost my_scripts]# ll /proc/$$/fd
    总用量 0
    lrwx------ 1 root root 64 2月  11 11:35 0 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 11:35 1 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 11:35 2 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 14:07 255 -> /dev/pts/2
    
    创建一个文件
    touch /root/file1.txt
    exec 3<> /root/file1.txt		在当前进程打开这个文件,3代表文件描述符	
    
    将文件中输入内容
    echo "123" >/proc/$$/fd/3
    cat /root/file1.txt		这是123就会出现在file1中,因为描述符3打开了这个文件
    
    删除/root/file1
    rm -rf /root/file
    这时ll /proc/$$/fd就会输出如下结果
    [root@localhost my_scripts]# ll /proc/$$/fd
    总用量 0
    lrwx------ 1 root root 64 2月  11 11:35 0 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 11:35 1 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 11:35 2 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 14:07 255 -> /dev/pts/2
    lrwx------ 1 root root 64 2月  11 11:35 3 -> /root/file1.txt (deleted)
    表示这个文件已经被删除了
    
    根据描述符恢复删除的文件
    cp /proc/$$/fd/3 /root/file1		文件恢复
    
    但是ll /proc/$$/fd/还是会提示3已经删除,这是由于每个文件都一个特定的iload编号
    
    关闭当前进程的文件描述符
    exec 3<&-
    
    

    2.再谈管道

    管道分为匿名管道和命名管道

    我们平时用的|叫匿名管道,其实匿名管道也是一个文件,只不过他是在我们心目中的,而命名管道是名副其实的文件,由mkfifo命令创建一个命名管道文件,命名管道文件可以跨终端输入,只显示一次。

    管道文件不会被覆盖,只有当有人读到这个文件才会消失

    终端1
    [root@localhost my_scripts]# mkfifo /tmp/fifo1
    终端2
    [root@localhost ~]# grep 'sda' /tmp/fifo1 等待输入
    终端1
    [root@localhost my_scripts]# ll /dev/ > /tmp/fifo1
    终端2
    brw-rw----  1 root disk      8,   0 2月  10 21:36 sda
    brw-rw----  1 root disk      8,   1 2月  10 21:36 sda1
    brw-rw----  1 root disk      8,   2 2月  10 21:36 sda2    获得内容
    
    再次查看则内容小时,若想再看则重新定向到文件
    

    3.并发控制实例

    脚本实现多线程并发控制的原理:

    ​ 首先定义并发的数量,然后创建管道文件,并往管道文件中插入数据(可以是空行),然后定义分隔符,以分隔符xx运行管道文件,在删除管道文件,因为删除管道文件不会影响句柄,在使用read -u命令读取分隔符内容,如果能读到数据则执行对应的后台进程,如果读取不到则一直等待,并发进程并不是等所有都执行完一轮后在执行新的一轮,而是完成一个后就会返回,比如控制 的并发数是50,那么始终都会是50个后台进程一起执行,直到程序结束

    3.1.ping主机实现并发控制

    #!/bin/bash
    #----------------------控制进程并发数量---------------------
    #-------------shell多进程/多线程------------------
    #定义控制并发的数量
    bfsl=10
    
    #定义管道文件
    fifofile=/tmp/$$.fifo
    
    #创建管道文件
    mkfifo $fifofile
    
    #以文件描述符3打开管道文件
    exec 3<> $fifofile
    
    #删除管道文件,因为文件描述符打开的文件即使删除句柄也不会被释放
    rm -rf $fifofile
    
    #循环往管道文件中写入内容
    for i in $(seq $bfsl)
    do
            echo >&3        #这个表示只写入回车
    done
    
    for i in {1..254}
    do
            read -u 3       #-u表示对文件描述符进行读取,如果能读取则执行下面的命令,如果不能则等待
            {
            ip=192.168.81.$i
            ping -c1 -W1 $ip &>/dev/null
            if [ $? -eq 0 ];then
                    echo "$ip is up"
            else
                    echo "$ip is down"
            fi
            echo >&3        #由于之前是从管道文件中读走了一行,这里要在还回去一行,让后面的进程进行使用
            }&
    done
    wait
    exec 3>&-               #释放文件描述符
    echo "finish.............."
    
    

    3.2.创建用户实现并发控制

    #!/bin/bash
    #------------创建用户实现并发控制------------
    #------------shell多线程/多进程-------------------
    #并发数量,一次性能同时存在多少个进程
    bfcs=50
    
    #管道文件
    fifofile=/tmp/user_$$.fifo
    
    #创建管道文件
    mkfifo $fifofile
    
    #打开管道文件并定义为分隔符4
    exec 4<> $fifofile
    
    #删除管道文件
    rm -rf $fifofile
    
    #向管道文件插入空行
    for i in $(seq $bfcs)
    do
            echo >&4
    done
    
    for i in $(seq -w 1000)
    do
            read -u 4       #读取分隔符4,如果读到行则执行下面命令,否则一直等待
            {
            user=qwe$i
            useradd $user
            echo "123" |passwd --stdin $user &>/dev/null
            if [ $? -eq 0 ];then
                    echo "$user is created..."
            fi
            echo >&4        #当运行完命令后则重新向管道文件插入新的行,以便后续进程进行使用
            }&
    done
    wait
    exec 4>&-               #当所有循环完成后释放分隔符
    echo "finish........."
    
    
    展开全文
  • 介绍如何并发运行shell脚本的模部分代码实现效率提升,简单介绍所涉及的前后台运行知识

    并发运行

    shell脚本一般运行模式就是按照脚本文件逐行运行,如例1:

    #!/bin/bash
    for i in $(seq 1 6)
    do
            sleep 1
            echo $i
    done
    echo "end <--"
    echo "time consume: ${SECONDS}s"
    

    在这里插入图片描述
    脚本总耗时6s
    加入for循环里面的操作步骤没有前后依赖关系,为了提高效率可以在循环体中添加&将其改成并发运行模式,如例2:

    #!/bin/bash
    for i in $(seq 1 6)
    do
    {
            sleep 1
            echo $i
    } &
    done
    wait  #等待for循环结束后再运行后面指令
    echo "end <--"
    echo "time consume: ${SECONDS}s"
    

    在这里插入图片描述
    当for循环数量庞大时,为了避免程序占用过多系统内存可以限制并发运行数量(比如最大并行数为3),如例3:

    #!/bin/bash
    # 创建有名管道
    fd_file="/tmp/fd1"
    [ -e "${fd_file}" ] && rm -f "${fd_file}"
    mkfifo "${fd_file}"
    # 创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性,linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2,所以这里由3开始
    exec 3<> "${fd_file}"
    # 关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了
    [ -e "${fd_file}" ] && rm -rf "${fd_file}"
    
    #创建令牌
    max=3
    for i in $(seq 1 ${max})
    do
        # echo 每次输出一个换行符,也就是一个令牌
        echo >&3
    done
    
    # read令牌,进行并发操作
    for i in $(seq 1 6)
    do
            # read 命令每次读取一行,也就是拿到一个令牌
            read -u3
            {
                    sleep 1
                    echo $i
                    # 执行完一个循环体将令牌放回管道
                    echo >&3
            } &
    done
    wait  #等待for循环结束后再运行后面指令
    exec 3<&-   # 关闭文件描述符的读
    exec 3>&-   # 关闭文件描述符的写
    echo "end <--"
    echo "time consume: ${SECONDS}s"
    

    在这里插入图片描述

    前后台运行

    Linux系统进程前后台运行相关的几个命令:&、ctrl+z、jobs、fg、bg

    1. & 最经常被用到,用在一个命令或代码块的最后(注意需要空格隔开),可以把命令或代码段放到后台执行;
    2. ctrl + z 可以将一个正在前台执行的命令放到后台,并且暂停;
    3. jobs 查看当前后台运行的命令列表;
    4. fg 将后台中的命令调至前台继续运行;
    5. bg 将一个在后台暂停的命令,变成继续执行(后台运行);
      以上面示例1的代码为例进行前后台运行调试结果如下,可以看到后台暂停运行的程序耗时还在继续计算中
      在这里插入图片描述
    展开全文
  • shell脚本并发数据到kafka topic需求:每秒发送大量数据到kafka,验证下游系统性能,数据中的时间戳要求为当前时间,可以之间采集系统当前时间替换文件中旧的时间戳,保证每次发送的数据都为最新时间。利用kafka自带...
  • 一、flock声明 Usage: flock [options] <file>|<directory> <command> [<argument>...] flock [options] <file>|<directory>...Manage file locks from shell scripts.
  • Shell脚本里实现并发操作,需要用到 for循环 &后台运行符 wait等待所有子进程结束 思路: 我们可以通过写一个for循环,控制每次需要批量操作的次数,然后封装一个方法,方法里进行批量操作,并将此方法用&...
  • /bin/bash#********************************##并发后台运行fun ##for wanggy 2012-01-25 ##note: ##fun_num fun函数后台运行次数 ##sql_num 每个函数sql运行次数 ##********************************##数据库...
  • 正常情况下,Shell脚本是串行执行的,一条命令执行完才会执行接下来的命令。如下代码: !/bin/bash for i in seq 1 10 do echo $i done echo “----end----” 脚本执行的结果如下: 1 2 3 4 5 6 7 8 9 10 ----end---...
  • 使用自动安装框架进行业务安装,调用SHELL脚本来修改权限等操作,包括修改server.xml配置等信息,某天两个安装任务一起运行时,发现密码字段为空,单独运行命令或单个安装任务则不会出现问题。 问题原因 SHELL代码...
  • shell脚本并发执行

    2019-09-22 16:36:20
    1,shell脚本如何获取时间 2,shell脚本如何传入参数 3,shell脚本并发执行 转载于:https://www.cnblogs.com/rrttp/p/9056512.html
  • #!/bin/bash #开始时间 begin=$(date +%s) #测试根目录 if [ ! -d $root_dir ]; then mkdir -p $root_dir fi cd $root_dir #批量创建目录函数 function create_dir() ... /bin/bash /roo...
  • shell脚本实现程序并发执行

    千次阅读 2021-03-14 10:25:03
    shell脚本实现程序并发执行 循环实现并发程序: 并发的实现原理是将进程放到后台运行,从而不影响当前shell的运行。在shell脚本中有&符号可以实现这个操作。 # !/usr/bin/bash echo "hello multiprocess" for ...
  • 正常执行 shell脚本中命令正常执行顺序是从上...多线程使命令并发执行,减少等待时间,使用wait作用等待所有在此shell脚本中启动的后台任务完成 #!/bin/bash for(( i = 0; i < ${count}; i++ )) do { commands1
  • https://blog.csdn.net/wangzhufei/article/details/87932048 Shell-使用&和wait让你的脚本并行执行 https://artisan.blog.csdn.net/article/details/87691890
  • shell实现并发控制

    2021-09-30 13:17:50
    需求: 并发检测1000台web服务器状态(或者并发为1000台web服务器分发文件等)如何用shell实现? 方案-1:(单进程) 思路:一个for循环1000次顺序执行1000次任务。 #!/bin/bash start_time=`date +%s` #定义脚本...
  • 编写shell脚本shell脚本放到应用模块下的bin目录下,如$FND_TOP/bin下,并将其从新命名为xxxx.prog文件 从shell脚本文件创建一个链接到$FND_TOP/bin/...
  • shell控制多并发数量——脚本方法

    千次阅读 2020-09-17 12:56:00
    但有一个问题,如果运行了好多个这样的脚本,都没释放,直到,达到系统设置的最大fd数,就打不开文件了。 也就是说,shell多进程,只有fd要释放这个潜在的危险,其它的风险都没有。但如果有fd要释放的,而没有弄限制...
  • 文章目录说明非并发原理并发原理以ping某段主机是否在线对并发进行说明普通脚本 说明 非并发原理 一般脚本正常情况下执行过程是按顺序执行的,简单来说就是上一个执行完毕了才会进行下一个; 代码和执行结果如下: ...
  • Shell脚本并发池控制

    2018-09-20 16:37:54
    for tbname in $(impala-shell --quiet -B -q "use $dbname;show tables;"|cat) do read -u10 { echo "use $dbname;MSCK REPAIR TABLE ${tbname};" hive -v -e "use $dbname;MSCK REPAIR TABLE ${tbname};...
  • /bin/bash# ----------------------------------------------------tmpfile=./$$.pid #$$是获取当前SHELL脚本进程的PIDmkfifo $tmpfile #生成一个FIFO管道文件exec 1000&lt;&gt;$tmpfile #绑定文件描述符...
  • 主要给大家分享了shell脚本实现多进程运行的方法示例,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
  • shell多进程并发执行脚本
  • Shell脚本中的多任务并发执行 需求 实现一个脚本能够使用ping检测网络的连通性 可以同时检测多个IP地址, 并且将检测结果输出 分析 正常情况下,Shell脚本中的命令是串行执行的,当一条命令执行完才会执行接下来的...
  • Shell脚本中的多任务并发执行

    千次阅读 2019-06-16 10:55:27
    正常情况下,Shell脚本中的命令是串行执行的,当一条命令执行完才会执行接下来的命令。比如下面这段代码: #!/bin/bash for i in {1..10};do echo $i done echo "END" 执行结果: 1 2 3 4 5 6 7 8 9 10 END 可以...
  • 本发明公开了一种限制shell 脚本并行执行 的方法,应用于linux 和unix 平台,包括:当有 shell 脚本需要执行时,脚本模块...测脚本,来检测死锁,没有多个并发进程对同一个 令牌进行操作,可以有效地解决死锁的问题。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,664
精华内容 17,065
关键字:

shell脚本的并发

友情链接: 算法效率.zip