J'ai une appli qui utilise plusieurs processus shell.
Chque processus est bien entendu identique, sauf aux données qu'il doit
traiter. C'est le rendu de ces données qui pose problème si je ne veux
pas avoir mes beaux tableaux ASCII intriqués les uns dans les autres.
Ce que je fais c'est que chaque traitement écrit dans un fichier temp,
et à la fin, je demande un sémaphore exclusif (que je peux
éventuellement attendre) sur le fichier de résultats, j'y appende les
résultats de la tâche, je lache le sémaphore, et j'attends le jeu de
données suivantes. Comme ça, tous les résultats sont bien séparés.
Est-ce une méthode correcte ? Chez moi, ça tourne sans problème depuis
10 ans avec des concurrences jusqu'à 30. Mais il y aurait mieux ?
Merci,
--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Alain Montfranc
Il se trouve que Xavier a formulé :
Bonjour,
J'ai une appli qui utilise plusieurs processus shell.
Chque processus est bien entendu identique, sauf aux données qu'il doit traiter. C'est le rendu de ces données qui pose problème si je ne veux pas avoir mes beaux tableaux ASCII intriqués les uns dans les autres.
Ce que je fais c'est que chaque traitement écrit dans un fichier temp, et à la fin, je demande un sémaphore exclusif (que je peux éventuellement attendre) sur le fichier de résultats, j'y appende les résultats de la tâche, je lache le sémaphore, et j'attends le jeu de données suivantes. Comme ça, tous les résultats sont bien séparés.
Est-ce une méthode correcte ? Chez moi, ça tourne sans problème depuis 10 ans avec des concurrences jusqu'à 30. Mais il y aurait mieux ?
Merci,
Ca semble bien... L'autre solution serait de faire communiquer chaque fils avec son père, charge à ce dernier de traiter les resultats reçus un par un, ce qui aurait l'avantage de permettre une ecrire sur stdout (quoi que tes fils peuvent partager le meme stdout)
Seul risque à mon avis : le plantage d'un fils alors que le semaphore est leve ==> les autres attendrons indéfiniment
Il se trouve que Xavier a formulé :
Bonjour,
J'ai une appli qui utilise plusieurs processus shell.
Chque processus est bien entendu identique, sauf aux données qu'il doit
traiter. C'est le rendu de ces données qui pose problème si je ne veux
pas avoir mes beaux tableaux ASCII intriqués les uns dans les autres.
Ce que je fais c'est que chaque traitement écrit dans un fichier temp,
et à la fin, je demande un sémaphore exclusif (que je peux
éventuellement attendre) sur le fichier de résultats, j'y appende les
résultats de la tâche, je lache le sémaphore, et j'attends le jeu de
données suivantes. Comme ça, tous les résultats sont bien séparés.
Est-ce une méthode correcte ? Chez moi, ça tourne sans problème depuis
10 ans avec des concurrences jusqu'à 30. Mais il y aurait mieux ?
Merci,
Ca semble bien... L'autre solution serait de faire communiquer chaque
fils avec son père, charge à ce dernier de traiter les resultats reçus
un par un, ce qui aurait l'avantage de permettre une ecrire sur stdout
(quoi que tes fils peuvent partager le meme stdout)
Seul risque à mon avis : le plantage d'un fils alors que le semaphore
est leve ==> les autres attendrons indéfiniment
J'ai une appli qui utilise plusieurs processus shell.
Chque processus est bien entendu identique, sauf aux données qu'il doit traiter. C'est le rendu de ces données qui pose problème si je ne veux pas avoir mes beaux tableaux ASCII intriqués les uns dans les autres.
Ce que je fais c'est que chaque traitement écrit dans un fichier temp, et à la fin, je demande un sémaphore exclusif (que je peux éventuellement attendre) sur le fichier de résultats, j'y appende les résultats de la tâche, je lache le sémaphore, et j'attends le jeu de données suivantes. Comme ça, tous les résultats sont bien séparés.
Est-ce une méthode correcte ? Chez moi, ça tourne sans problème depuis 10 ans avec des concurrences jusqu'à 30. Mais il y aurait mieux ?
Merci,
Ca semble bien... L'autre solution serait de faire communiquer chaque fils avec son père, charge à ce dernier de traiter les resultats reçus un par un, ce qui aurait l'avantage de permettre une ecrire sur stdout (quoi que tes fils peuvent partager le meme stdout)
Seul risque à mon avis : le plantage d'un fils alors que le semaphore est leve ==> les autres attendrons indéfiniment
xavier
Alain Montfranc wrote:
Seul risque à mon avis : le plantage d'un fils alors que le semaphore est leve ==> les autres attendrons indéfiniment
Celui-là, je le gère aussi : si j'attends plus de 5 fois la durée maxi estimée d'une éxécution normale, je force le sémaphore.
Merci,
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Alain Montfranc <mort@aux.spammeurs> wrote:
Seul risque à mon avis : le plantage d'un fils alors que le semaphore
est leve ==> les autres attendrons indéfiniment
Celui-là, je le gère aussi : si j'attends plus de 5 fois la durée maxi
estimée d'une éxécution normale, je force le sémaphore.
Merci,
--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
Seul risque à mon avis : le plantage d'un fils alors que le semaphore est leve ==> les autres attendrons indéfiniment
Celui-là, je le gère aussi : si j'attends plus de 5 fois la durée maxi estimée d'une éxécution normale, je force le sémaphore.
Merci,
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Nicolas George
Xavier, dans le message <1kar63q.13qkseej9peqyN%, a écrit :
Ce que je fais c'est que chaque traitement écrit dans un fichier temp, et à la fin, je demande un sémaphore exclusif (que je peux éventuellement attendre) sur le fichier de résultats, j'y appende les résultats de la tâche, je lache le sémaphore, et j'attends le jeu de données suivantes. Comme ça, tous les résultats sont bien séparés.
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
Xavier, dans le message <1kar63q.13qkseej9peqyN%xavier@groumpf.org>, a
écrit :
Ce que je fais c'est que chaque traitement écrit dans un fichier temp,
et à la fin, je demande un sémaphore exclusif (que je peux
éventuellement attendre) sur le fichier de résultats, j'y appende les
résultats de la tâche, je lache le sémaphore, et j'attends le jeu de
données suivantes. Comme ça, tous les résultats sont bien séparés.
C'est correct en théorie. Cependant, tu devrais préciser quel type de
sémaphore tu utilises, parce que certaines API sont une calamité.
Xavier, dans le message <1kar63q.13qkseej9peqyN%, a écrit :
Ce que je fais c'est que chaque traitement écrit dans un fichier temp, et à la fin, je demande un sémaphore exclusif (que je peux éventuellement attendre) sur le fichier de résultats, j'y appende les résultats de la tâche, je lache le sémaphore, et j'attends le jeu de données suivantes. Comme ça, tous les résultats sont bien séparés.
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
xavier
Nicolas George <nicolas$ wrote:
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation ne garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé dans la manpage.
En Perl, j'utilise plutôt POSIX::RT::Semaphore
Merci,
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Nicolas George <nicolas$george@salle-s.org> wrote:
C'est correct en théorie. Cependant, tu devrais préciser quel type de
sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS,
lockfile(1), plus souple que lockf(1), même si son implémentation ne
garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé
dans la manpage.
En Perl, j'utilise plutôt POSIX::RT::Semaphore
Merci,
--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation ne garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé dans la manpage.
En Perl, j'utilise plutôt POSIX::RT::Semaphore
Merci,
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Nicolas George
Xavier, dans le message <1karuxz.1kq5k29db4zxjN%, a écrit :
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation ne garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé dans la manpage.
C'est raisonnable. Mais tu aurais plutôt dû parler de verrou que de sémaphore, la sémantique n'est pas exactement la même.
Xavier, dans le message <1karuxz.1kq5k29db4zxjN%xavier@groumpf.org>, a
écrit :
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS,
lockfile(1), plus souple que lockf(1), même si son implémentation ne
garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé
dans la manpage.
C'est raisonnable. Mais tu aurais plutôt dû parler de verrou que de
sémaphore, la sémantique n'est pas exactement la même.
Xavier, dans le message <1karuxz.1kq5k29db4zxjN%, a écrit :
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation ne garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas précisé dans la manpage.
C'est raisonnable. Mais tu aurais plutôt dû parler de verrou que de sémaphore, la sémantique n'est pas exactement la même.
xavier
Nicolas George <nicolas$ wrote:
la sémantique n'est pas exactement la même.
Exact. Merci de la précision.
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Nicolas George <nicolas$george@salle-s.org> wrote:
la sémantique n'est pas exactement la même.
Exact. Merci de la précision.
--
XAv
In your pomp and all your glory you're a poorer man than me,
as you lick the boots of death born out of fear.
(Jethro Tull)
-- XAv In your pomp and all your glory you're a poorer man than me, as you lick the boots of death born out of fear. (Jethro Tull)
Cyrille Lefevre
Le 15/11/2011 11:48, Xavier a écrit :
Nicolas George<nicolas$ wrote:
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation n e garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas pr écisé dans la manpage.
PS : bon, là, d'accord, j'me suis éclaté à implémenter siglal e t atexit en shell, le principal étant la function lock() à base de ln.
attention, les fichiers doivent être dans le même sens, ex. : proc 1 : lock a b c proc 2 : lock a c proc 3 : lock b c et non proc 2 : lock c a, sinon, opssibilité de deadlock
un autre version de la function lock avec timeout plus adapté (retry si un nouveau lock a été posé dans l'interal d'attente) sans tout le t outim autour est :
if (( rc == 0 )); then if (( checktime > 0 )); then integer difftime=$(${_FCDATE} -d "${temp}" "${lock}") if (( difftime > checktime )); then ${_RM} -f "${lock}" fi fi integer time0="${SECONDS}" (( time0 -= 1 )) until ${DEVNULL2} ${_LN} "${temp}" "${lock}"; do if (( timeout == 0 )); then rc=1 break fi if (( timeout > 0 && ( SECONDS - time0 ) > timeout )); then if (( checktime > 0 )); then difftime=$(${_FCDATE} -d "${temp}" "${lock}") time0="${SECONDS}" (( time0 -= 1 )) if (( difftime < 0 )); then continue elif (( difftime > checktime )); then ${_RM} -f "${lock}" continue fi else rc=1 break fi fi sleep "${sleeptime}" ${_TOUCH} "${temp}" done fi ) set +x; eval ${trace} return ${rc} }
function _unlock # file... { set +x; eval $(trace -q _unlock "$@")
typeset file=$1 typeset dir="${TMPDIR:-/var/tmp}"
if [[ -z ${file} ]]; then file="${dir}/${_PROGNAME}" elif [[ ${file} != *'/'* ]]; then file="${dir}/${file}" fi
typeset lock="${file}.lck" ${_RM} -f "${lock}"
set +x; eval ${trace} return 0 }
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
Le 15/11/2011 11:48, Xavier a écrit :
Nicolas George<nicolas$george@salle-s.org> wrote:
C'est correct en théorie. Cependant, tu devrais préciser quel type de
sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS,
lockfile(1), plus souple que lockf(1), même si son implémentation n e
garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas pr écisé
dans la manpage.
PS : bon, là, d'accord, j'me suis éclaté à implémenter siglal e t atexit
en shell, le principal étant la function lock() à base de ln.
attention, les fichiers doivent être dans le même sens, ex. :
proc 1 : lock a b c
proc 2 : lock a c
proc 3 : lock b c
et non proc 2 : lock c a, sinon, opssibilité de deadlock
un autre version de la function lock avec timeout plus adapté (retry si
un nouveau lock a été posé dans l'interal d'attente) sans tout le t outim
autour est :
if (( rc == 0 )); then
if (( checktime > 0 )); then
integer difftime=$(${_FCDATE} -d "${temp}"
"${lock}")
if (( difftime > checktime )); then
${_RM} -f "${lock}"
fi
fi
integer time0="${SECONDS}"
(( time0 -= 1 ))
until ${DEVNULL2} ${_LN} "${temp}" "${lock}"; do
if (( timeout == 0 )); then
rc=1
break
fi
if (( timeout > 0 && ( SECONDS - time0 ) >
timeout )); then
if (( checktime > 0 )); then
difftime=$(${_FCDATE} -d
"${temp}" "${lock}")
time0="${SECONDS}"
(( time0 -= 1 ))
if (( difftime < 0 )); then
continue
elif (( difftime > checktime
)); then
${_RM} -f "${lock}"
continue
fi
else
rc=1
break
fi
fi
sleep "${sleeptime}"
${_TOUCH} "${temp}"
done
fi
)
set +x; eval ${trace}
return ${rc}
}
function _unlock # file...
{
set +x; eval $(trace -q _unlock "$@")
typeset file=$1
typeset dir="${TMPDIR:-/var/tmp}"
if [[ -z ${file} ]]; then
file="${dir}/${_PROGNAME}"
elif [[ ${file} != *'/'* ]]; then
file="${dir}/${file}"
fi
typeset lock="${file}.lck"
${_RM} -f "${lock}"
set +x; eval ${trace}
return 0
}
Cordialement,
Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
C'est correct en théorie. Cependant, tu devrais préciser quel type de sémaphore tu utilises, parce que certaines API sont une calamité.
Comme c'est du script shell, j'utilise un sémaphore au niveau du FS, lockfile(1), plus souple que lockf(1), même si son implémentation n e garantit pas stricto sensu l'atomicité, en tout cas ça n'est pas pr écisé dans la manpage.
PS : bon, là, d'accord, j'me suis éclaté à implémenter siglal e t atexit en shell, le principal étant la function lock() à base de ln.
attention, les fichiers doivent être dans le même sens, ex. : proc 1 : lock a b c proc 2 : lock a c proc 3 : lock b c et non proc 2 : lock c a, sinon, opssibilité de deadlock
un autre version de la function lock avec timeout plus adapté (retry si un nouveau lock a été posé dans l'interal d'attente) sans tout le t outim autour est :
if (( rc == 0 )); then if (( checktime > 0 )); then integer difftime=$(${_FCDATE} -d "${temp}" "${lock}") if (( difftime > checktime )); then ${_RM} -f "${lock}" fi fi integer time0="${SECONDS}" (( time0 -= 1 )) until ${DEVNULL2} ${_LN} "${temp}" "${lock}"; do if (( timeout == 0 )); then rc=1 break fi if (( timeout > 0 && ( SECONDS - time0 ) > timeout )); then if (( checktime > 0 )); then difftime=$(${_FCDATE} -d "${temp}" "${lock}") time0="${SECONDS}" (( time0 -= 1 )) if (( difftime < 0 )); then continue elif (( difftime > checktime )); then ${_RM} -f "${lock}" continue fi else rc=1 break fi fi sleep "${sleeptime}" ${_TOUCH} "${temp}" done fi ) set +x; eval ${trace} return ${rc} }
function _unlock # file... { set +x; eval $(trace -q _unlock "$@")
typeset file=$1 typeset dir="${TMPDIR:-/var/tmp}"
if [[ -z ${file} ]]; then file="${dir}/${_PROGNAME}" elif [[ ${file} != *'/'* ]]; then file="${dir}/${file}" fi
typeset lock="${file}.lck" ${_RM} -f "${lock}"
set +x; eval ${trace} return 0 }
Cordialement,
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.