[gull] Truc et astuces: multithread en bash
felix
felix at f-hauri.ch
Tue Dec 29 12:48:40 CET 2020
On Mon, Dec 28, 2020 at 11:29:41PM +0100, Daniel Cordey wrote:
> On 28/12/2020 21:44, felix wrote:
> > Du point de vue du script lui même, il converse *effectivement* avec
> > au moins deux thread indépendant: Les pings et l'utilisateur
> ..
> Tu fais un fork, suivit d'un exec du code /usr/bin/ping. Donc un autre PID
> -> autre process -> Pas un thread !
Oui, je fais un fork (dans ce cas), mais le script, lui, converse avec
le ${fd}. De ce point de vue, il s'agit d'un flux indépendant de l'entrée
standard.
J'aurrai pu écrire:
for i in {1..255};do
exec {fd[i]}<>/dev/tcp/192.168.1.$i/22 # Ceci n'est pas un fork!
done
declare -p fd
l=10
while ((l--)) && ! read -t .5 -rsn 1 foo;do
for i in ${!fd[@]} ;do
read -t 0 -u ${fd[i]} &&
read -u ${fd[i]} line && echo 192.168.1.$i: $line
done
done
Du point de vue du script bash, cela revient au même: plusieurs fils
de discutions à gérer indépendament.
Dans le cas de mon script qui utilise ghostscript, je parallélise
plusieurs commandes graphiques en utilisant (du point de vue du script)
plusieurs $fd différents, afin de paralléliser les opérations de
conversion, tout en évitant la sur-occupation du disque.
Bon, puisqu'on en est là, je poste un bout de mon script (Il n'est pas
abouti, fait pour l'instant 125 lignes)
73 exec {pnm}<> <(:)
74 coproc gs -q -sDEVICE=pnmraw -dSAFER -r$(( ores * scale )) -dBATCH \
75 -sOutputFile=/dev/fd/$pnm "$1" -c quit
76 page=1 gspid=$! loop=true
79 while $loop && [ -d /proc/$gspid ] ;do
80 printf -v file page-%11d $((page++))
81
82 numcolor=$(
83 ppmhist -noheader < <(
84 pnmnoraw </dev/fd/${pnm} |
85 tee >(
86 pnmscale $div |
87 tee >(pnmtojpeg -q $jpegqual >$file.jpg) >tmpfile)
88 ) | wc -l
89 )
90 numcolor=$(( numcolor >= maxcol ? 255 : numcolor * shade ))
91
92 read -u $COPROC -t 1 foo || loop=false # wait for showpage msg
93 echo '' >&${COPROC[1]} # hit <return>
94
95 pnmquant <tmpfile $numcolor 2>/dev/null |
96 pnmtopng >$file.png 2>/dev/null
97 size=$(pnmfile <tmpfile)
103...
104 { read pngsz;read jpgsz ;} < <(stat -c %s $file.{png,jpg})
105 (( pngsz > jpgsz )) && rm $file.png tmpfile|| rm $file.jpg tmpfile
111... done
Le script gère effectivement plusieurs fils d'entrée/sorties, simulténament
et interractivement.
Il s'agit donc d'une application multitâche, avec plein de forks, générés
au travers d'un processus (script) multithread qui gères les interactions.
(à la ligne 93, ghostscript commence à rasteriser la page suivante, tandis
que le script fini la génération de l'image et la sélection de la plus
légère.
A la ligne 84, un nouveau process et généré pour chaque page générée par un
seul process ghostscript qui traite le fichier en entier et un seul passage)
C'est de la sémantique.
Il me semble de la difference entre multitâche et multithread est:
La différence entre le fait de lancer plusieurs tâches en parallel
et le fait de converser avec plusieurs interlocuteurs simultanément.
--
Félix Hauri - <felix at f-hauri.ch> - http://www.f-hauri.ch
More information about the gull
mailing list