#!/usr/bin/sh # #!ident @(#) parallel.sh 1.1 (Cyrille.Lefevre-lists%nospam@laposte.net.invalid) Mon Jun 28 17:42:42 2010 # supprimer "%nospam" et ".invalid" pour me repondre. # remove "%nospam" and ".invalid" to answer me. # # Copyright (c) 2010 Cyrille Lefevre. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. The name of the authors and contributors may not be used to # endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS # OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. function loop { typeset maxpid=$1 typeset pid= newpids= typeset -i sleep=0 while (( npid >= maxpid )); do newpids= sleep=1 for pid in ${pids}; do if kill -0 "${pid}" 2> /dev/null; then newpids="${newpids} ${pid}" else sleep=0 (( npid -= 1 )) wait "${pid}" echo "${pid}: done" fi done pids=${newpids} (( sleep != 0 )) && sleep 1 done } function parallel { typeset ncpu=$1 nice=$2 shift 2 typeset -i npid=0 typeset pids= while read -r; do case ${REPLY} in ''|'#'*) continue ;; ncpu=*|nice=*) echo ${REPLY} eval ${REPLY} continue ;; rset) echo rset ncpu=${_ncpu} continue ;; wait) echo wait loop 1 continue ;; esac loop "${ncpu}" ${REPLY} & (( npid += 1 )) pids="${pids} $!" [[ -n ${nice} && ${nice} != 0 ]] && sleep 1 && renice ${nice} $! echo "$!: $REPLY" done loop 1 } _ncpu=$1 if (( ${_ncpu:-0} < 1 )); then case $(uname) in AIX) _ncpu=$(LC_ALL=C lsdev -c processor | grep -c Avail) ;; Darwin) #noht#_ncpu=$(sysctl -n hw.physicalcpu) _ncpu=$(sysctl -n hw.availcpu) # was logicalcpu ;; FreeBSD) _ncpu=$(sysctl -n hw.ncpu) ;; HP-UX) _ncpu=$(ioscan -fkC processor | grep -c processor) ;; CYGWIN*) # _ncpu=${NUMBER_OF_PROCESSORS} _ncpu=$(grep -c processor /proc/cpuinfo) ;; Linux) #noht#_ncpu=$(grep 'physical id' /proc/cpuinfo | sort -u | wc -l) _ncpu=$(grep -c processor /proc/cpuinfo) ;; SunOS) _ncpu=$(LC_ALL=C psrinfo -v | grep -c on-line) ;; esac fi _coef=$2 if (( ${_coef:-0} > 1 )); then (( _ncpu *= _coef )) fi _nice=$3 _time0=${SECONDS} parallel ${_ncpu:-1} ${_nice:-0} "$@" (( _time0 -= -${SECONDS} )) echo elapsed: ${_time0}