Skip to content
Snippets Groups Projects
bash_multithread.sh 2.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/bin/bash
    
    # slightly modified implementation of sub-process limiter
    # by paxdiablo. See http://stackoverflow.com/a/1685440
    
    # bgxupdate - update active processes in a group.
    #   Works by transferring each process to new group
    #   if it is still active.
    # in:  bgxgrp - current group of processes.
    # out: bgxgrp - new group of processes.
    # out: bgxcount - number of processes in new group.
    
    bgxupdate() {
        bgxoldgrp=${bgxgrp}
        bgxgrp=""
        ((bgxcount = 0))
        bgxjobs=" $(jobs -pr | tr '\n' ' ')"
        for bgxpid in ${bgxoldgrp} ; do
            echo "${bgxjobs}" | grep " ${bgxpid} " >/dev/null 2>&1
            if [[ $? -eq 0 ]] ; then
                bgxgrp="${bgxgrp} ${bgxpid}"
                ((bgxcount = bgxcount + 1))
            fi
        done
    }
    
    # bgxlimit - start a sub-process with a limit.
    #   Loops, calling bgxupdate until there is a free
    #   slot to run another sub-process. Then runs it
    #   an updates the process group.
    # in:  $1     - the limit on processes.
    # in:  $2+    - the command to run for new process.
    # in:  bgxgrp - the current group of processes.
    # out: bgxgrp - new group of processes
    
    bgxlimit() {
        bgxmax=$1 ; shift
        bgxupdate
        while [[ ${bgxcount} -ge ${bgxmax} ]] ; do
            sleep 0.1
            bgxupdate
        done
        if [[ "$1" != "-" ]] ; then
            "$@" &
            bgxgrp="${bgxgrp} $!"
        fi
        # echo '[' ${bgxgrp} ']'
    }
    
    # bgxwait - wait for sub-processes to finish
    #   Loops calling bgxupdate until there is something
    #   in a process group
    
    bgxwait() {
        bgxupdate
        while [[ ${bgxcount} -ne 0 ]] ; do
            oldcount=${bgxcount}
            while [[ ${oldcount} -eq ${bgxcount} ]] ; do
                sleep 0.1
                bgxupdate
            done
            # echo '[' ${bgxgrp} ']'
        done
    }
    
    bgxtest() {
        callback() {
            id=$1 ; shift
            echo start $id $(date | awk '{print $4}') "$BASHPID"
            sleep ${id}0
            echo end $id $(date | awk '{print $4}') "$BASHPID"
        }
    
        # Test program, create group and run 6 sleeps with
        #   limit of 3.
    
        bgxgrp=""
        for i in 1 2 3 4 5 6 ; do
            bgxlimit 3 callback ${i}
        done
    
        # Wait until all others are finished.
        bgxwait;
    }