如何在不使用 Kill 的情况下停止 while 循环后台进程?

如何在不使用 Kill 的情况下停止 while 循环后台进程?

我有一个 bash 脚本,其中包含while 循环后台进程如何停止 while 循环而不终止进程,因此通过设置停止旗帜

注意:如果我使用,我的脚本就可以工作但与停止标志没用

这是我的脚本的演示(使用 Kill):

#!/bin/bash


background_processes=()


trap ctrl_c INT
ctrl_c() {
    printf "\n[~] Killing background processes...\n"
    for pid in "${background_processes[@]}"
        do
          kill $pid > /dev/null 2>&1
        done

}

background_process() {
    while true
        do
         sleep 5
         printf "Hello World!\n"
        done

}

start() {

    for t in $(seq 1 10)
        do 
            background_process &
            background_processes+=(${!})
        done

    wait
}
printf "\n[I] Press 'ctrl+c' to kill background processes! \n"
start

这个方法很好用,但另一种方法不行!

这是我的相同演示,但带有停止标志(不行!)

#!/bin/bash


STOP=0
threads=10
finished_threads=0

trap ctrl_c INT
ctrl_c() {
    printf "\n[~] Stopping background processes...\n"
    STOP=1
    # here i was checking that all the background processes is finish
    while true
        do
         if [[ $finished_threads == $threads ]]
             then
                break
         fi
        done
    printf "\n[+] Done\n"
 

}

background_process() {
    while true
        do
         sleep 5
         printf "Hello World!\n"
         if [[ $STOP = 1 ]]
             then
                ((finished_threads++))
                break
         fi
        done

}

start() {

    for t in $(seq 1 $threads)
        do 
            background_process &
        done

    wait
}
printf "\n[I] Press 'ctrl+c' to stop background processes! \n"
start

谁能告诉我为什么这不起作用?

PS:顺便说一句,我是阿拉伯人,如果我的英语语法不好,很抱歉

答案1

第二个示例不起作用的原因是每个进程都有自己的地址空间,因此$STOP为主进程中的变量设置值不会影响后台进程读取的值。

终止后台工作人员的直接方法是使用信号,就像您在第一个示例中所做的那样。另一种方法是使用管道进行同步,例如,让子进程使用非阻塞读取,父进程在想要终止时关闭管道,子进程在检测到管道已关闭时退出。

相关内容