0

i'm running a script that calls a child script that in turn calls other child scripts and processes.

some of the child processes use a lot of disk io and cpu, and overheats the cpu, causing a crash or errors. i guess i can thank intel for that. this isn't a request for information to fix my cpu.

i want to pause the script for 2mins every 5mins, to allow the cpu to cool down.

this is in my parent script:

for dir in * ; do
        if [ -d "$d" ]; then
                printf "$dir."
                ./subscript.sh "${dir}" & 
                        echo "$!" > ./"${dir}.pid" & 
                        ./pauser.sh "${dir}"
                #rm ./"{d}.pid"
        touch "{d}.pid.ended"
        fi
done

and this is my pauser.sh script:

#!/bin/bash
pauser() {
        printf "@" && 
                sleep "${2}m" && 
                check_running "${1}" && 
                kill -STOP "$(cat ${1}.pid)" && 
                sleep "${3}m" && 
                printf "." && 
                check_running "${1}" && 
                kill -CONT "$(cat ${1}.pid)"
}
check_running() {
        if [ -f "${1}.pid.ended" ]; then
                rm "${1}.pid.ended"
                exit 0
        fi
}
while true
do
        if [ -f "${1}.pid.ended" ]; then
                rm "${1}.pid.ended"
                exit 0
        else
                pauser "${1}" "5" "2"
        fi
done

this pauser script doesn't pause the child of child processes, i think because the child of child scripts/processes have different pid's.

i've read that child of child processes can be grouped, if so, how do i pause and resume the entire group of child processes from the parent script?

  • See https://unix.stackexchange.com/questions/484442/how-can-i-get-the-pid-of-a-subshell , you should get the pid when you create the children processes, and them pass them as an argument to the pauser script. – dcom-launch Sep 09 '21 at 13:16
  • 1
    thanks @dcom-launch, but i think i found another way from stackexchange by @PSkocik https://stackoverflow.com/questions/6549663/how-to-set-process-group-of-a-shell-script#answer-45112755 by using set +m to spawn each successive child process in it's own group, then by using kill -STOP "-${pid} the negative before $pid allows to pause the entire group, but not the parent script – laughing muppet Sep 09 '21 at 13:27
  • If your CPU is overheating, then there's not enough cooling. This is not a fault of the CPU manufacturer, but of whoever put the machine together. I have not seen a single properly spec-ed system overheat under normal or even high work loads. – Kusalananda Sep 09 '21 at 14:49
  • @Kusalananda i think it's the external usb drive, perhaps a caching problem. it's just a cheap 4tb drive (the cheapest i could find) and i don't think it was designed for constant use. i'd buy a nas but i can't afford it. – laughing muppet Sep 09 '21 at 15:51

1 Answers1

0

thanks to @PSkocik here, i can set -m before the child process, and set +m afterward, which will set each child process in it's own group.

all child processes of that child process will also be in the same group, so they all have the same group id.

by using kill -STOP -${pid_to_pause} the negative before the process id pauses the entire group, because the group id also happens to be the most senior of the group's pid, but not the parent script, because of set -m

my new parent script:

for dir in * ; do
    if [ -d "$dir" ]; then
        printf "$d."
        set -m
        ./subscript.sh "${dir}" & 
            echo "$!" > ./"${d}.pid" & 
            ./pauser.sh "${dir}"
        #wait
        set +m
        #rm ./"{dir}.pid"
        touch "{d}.pid.ended"
    fi
done

my new pauser script:

#!/bin/bash
pauser() {
    sleep "${2}m" && 
        check_running "${1}" && 
        printf "," && 
        kill -STOP "-$(cat ${1}.pid)" && 
        sleep "${3}m" && 
        check_running "${1}" && 
        printf "." &&
        kill -CONT "-$(cat ${1}.pid)"
}
check_running() {
    if [ -f "${1}.pid.ended" ]; then
        rm "${1}.pid.ended"
        exit 0
    fi
}
while true
do
    if [ -f "${1}.pid.ended" ]; then
        rm "${1}.pid.ended"
        exit 0
    else
        pauser "${1}" "15" "5"
    fi
done

  • i thought this was the solution, however when running a process in a grandchild script, it hangs. i've since played with the code and now i'm getting "error while changing user terminal properties" when running an external process – laughing muppet Sep 09 '21 at 17:22