2010-10-08 12 views
1

J'ai une fonction bash appelée qui doit être appelée par une interruption EXIT après la première fois qu'elle est appelée. La fonction remet le piège à feu dès que la fonction se termine.Comment définir à nouveau le trap de bash dans le code trap?

echo 0 > .i 
function launchNextExperiment 
{ 
(# Run in nested subshell 

    # Implement a mutex lock, not shown 

    j=`cat .i` 
    if [ $j -lt $k ] 
    then 
    trap launchNextExperiment EXIT # set trap for this nested subshell 

    ./doStuff & 

    let j=j+1 
    echo $j > .i # variables are not known in outer shell, therefore use 
       # the file .i as a counter 
    fi 

    wait # wait for doStuff to return from background before exiting 
     # from this nested shell and causing an EXIT signal 
) 
} 

launchNextExperiment & 

Le problème que j'ai est que le piège est tiré seulement une fois, autrement dit doStuff n'est exécutée deux fois.

La raison pour laquelle je ne suis pas en utilisant une simple boucle pour faire doStuffk fois est que j'appelle en fait la fonction launchNextExperiment une fois pour chacun d'un sous-ensemble de mes unités centrales, et ne veulent qu'une instance de doStuff pour fonctionner sur un processeur à la fois car il est très intensif de traitement. C'est aussi pourquoi j'ai un verrou de mutex. Ensuite, dès qu'une instance de doStuff retourne, je veux lancer la prochaine k instances de doStuff (en fait, ils ont toutes différentes simulations).

Comment puis-je faire en sorte que le piège est défini pour chaque sous-shell imbriqué, et à la fin launchNextExperiment est exécuté k fois, mais une seule doStuff par CPU?

+0

Le piège EXIT est pour les tâches de nettoyage ne sont pas à la logique du programme. – ceving

Répondre

0

pas la réponse à votre question, mais ce que vous essayez d'accomplir peut se faire sans pièges et sous-couches:

echo 0>i 
k=10 
dispatch_work() 
{ 
    mutex_lock 
    i=$(<i) 
    let i++ 
    echo $i>i 
    mutex_unlock 

    if [ $i < $k ]; do 
    do_work $i 
    dispatch_work 
    fi 
} 

for c in $(seq 1 $cpus); do 
    dispatch_work & 
done