【问题标题】:bash while loop threadingbash while 循环线程
【发布时间】:2014-05-27 17:46:28
【问题描述】:

我有一个 while 循环从 $hosts 读取行

while read line
do
    ip=$line
    check
done < $hosts

我的问题是我是否可以使用某种方式来加快速度或一次在 10 台主机上运行检查,并且每次检查都在不同的 IP 上,并在检查完 $host 中的所有 IP 后完成? 谢谢

【问题讨论】:

  • 完全正确,Bash 无法访问线程。后台作业运行一个单独的进程,而不是在线程中。所以严格来说,这是多处理,而不是多线程。

标签: multithreading bash shell while-loop


【解决方案1】:

您可以启动多个进程,每个进程调用函数check 并等待它们完成。

while read line 
do 
  ip=$line
  check &
done < $hosts
wait # wait for all child processes to finish

这是否会提高速度取决于可用的处理器和函数check 的实现。您必须确保 check 在迭代之间没有数据依赖关系。

【讨论】:

    【解决方案2】:

    您可以通过&amp;将任务发送到后台 如果您打算等待所有这些都完成,您可以使用wait 命令:

    process_to_background &
    echo Processing ...
    wait
    echo Done
    

    如果您想等待一个(或几个)特定任务,您可以在后台启动给定任务的pid

    important_process_to_background &
    important_pid=$!
    while i in {1..10}; do
        less_important_process_to_background $i &
    done
    
    wait $important_pid
    echo Important task finished
    
    wait
    echo All tasks finished
    

    请注意:后台进程可能会弄乱输出,因为它们将异步运行。您可能希望使用命名管道来收集它们的输出。

    编辑

    正如 cmets 中所问的,可能需要限制分叉的后台进程。在这种情况下,您可以跟踪已启动的后台进程数量,并通过命名管道与它们通信。

    mkfifo tmp # creating named pipe
    
    counter=0
    while read ip
    do
      if [ $counter -lt 10 ]; then # we are under the limit
        { check $ip; echo 'done' > tmp; } &
        let $[counter++];
      else
        read x < tmp # waiting for a process to finish
        { check $ip; echo 'done' > tmp; } &
      fi
    done
    cat /tmp > /dev/null # let all the background processes end
    
    rm tmp # remove fifo
    

    【讨论】:

    • 这个循环会遍历 $hosts 中的每个主机吗?即使有10多个?我不想启动超过 10 个进程,这可能会占用太多资源。
    • 这只是一个如何使用后台进程以及如何等待它们的示例。如果要指定听起来像线程池的最大线程数。为此,我添加了一个示例,但它可能不是最好的实现
    • 计数器什么时候递减?
    • 每次读取一行都会递减。 Echo 也打印新行。
    • @Interlated,我们从不递减计数器:计数器用于初始化数量有限的后台进程的“池”,然后只要之前启动的后台进程仍然需要,我们就会创建一个新的后台进程完成
    【解决方案3】:

    使用GNU Parallel:

    parallel check ::: $hosts
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      • 2013-01-12
      • 2012-10-28
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多