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
Stephane CHAZELAS
2008-12-16, 11:07(+00), Antoine:
Salut,
Quand je fais un: % find / | head
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
Donc:
1- pour qu'il meurt, il faut qu'il ecrive quelque chose apres que head se termine, donc il peut ne pas se terminer tout de suite s'il ne trouve pas de fichier.
2- find peut ecrire bien plus de 10 lignes avant d'etre tué, parce que: - dans un pipe, on peut ecrire pas mal avant que l'autre ne lise (ya un buffer qui peut contenir plusieurs dixaines de kB suivant les implementations), donc apres, c'est une histoire de quel process est schedulé. - "head" va lire morceau par morceau, les morceaux faisant typiquement 4, 5 or 8 kB selon les implementation de stdio. mais note que le read(0, ...) retournera mois que sizeof(buf) si find n'en a pas ecrit autant au moment ou head fait appel a read(). - surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
-- Stéphane
2008-12-16, 11:07(+00), Antoine:
Salut,
Quand je fais un:
% find / | head
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des
qu'il a trouvé 10 caracteres "NL" dans son input il va se
terminer, ce qui va fermer la sortie du pipe. A partir de ce
moment la, des que find va faire un write(1, ...), il va se
prendre un signal SIGPIPE qui va le tuer.
Donc:
1- pour qu'il meurt, il faut qu'il ecrive quelque chose apres
que head se termine, donc il peut ne pas se terminer tout de
suite s'il ne trouve pas de fichier.
2- find peut ecrire bien plus de 10 lignes avant d'etre tué,
parce que:
- dans un pipe, on peut ecrire pas mal avant que l'autre ne
lise (ya un buffer qui peut contenir plusieurs dixaines de kB
suivant les implementations), donc apres, c'est une histoire
de quel process est schedulé.
- "head" va lire morceau par morceau, les morceaux faisant
typiquement 4, 5 or 8 kB selon les implementation de stdio.
mais note que le read(0, ...) retournera mois que sizeof(buf)
si find n'en a pas ecrit autant au moment ou head fait appel a
read().
- surtout, find lui-meme va ecrire morceau par morceau puisque
son stdout n'est pas un terminal, donc ne va probablement rien
ecrire avant d'avoir trouver suffisamment de fichier pour
remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit
faire des puts() ou printf()).
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
Donc:
1- pour qu'il meurt, il faut qu'il ecrive quelque chose apres que head se termine, donc il peut ne pas se terminer tout de suite s'il ne trouve pas de fichier.
2- find peut ecrire bien plus de 10 lignes avant d'etre tué, parce que: - dans un pipe, on peut ecrire pas mal avant que l'autre ne lise (ya un buffer qui peut contenir plusieurs dixaines de kB suivant les implementations), donc apres, c'est une histoire de quel process est schedulé. - "head" va lire morceau par morceau, les morceaux faisant typiquement 4, 5 or 8 kB selon les implementation de stdio. mais note que le read(0, ...) retournera mois que sizeof(buf) si find n'en a pas ecrit autant au moment ou head fait appel a read(). - surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
-- Stéphane
Nicolas George
Stephane CHAZELAS wrote in message :
- surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un fflush après chaque nom de fichier, pour ne pas retarder la suite du traitement. Et de fait, au moins GNU find se comporte ainsi.
Stephane CHAZELAS wrote in message
<slrngkf3ve.6t3.stephane.chazelas@spam.is.invalid>:
- surtout, find lui-meme va ecrire morceau par morceau puisque
son stdout n'est pas un terminal, donc ne va probablement rien
ecrire avant d'avoir trouver suffisamment de fichier pour
remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit
faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un
fflush après chaque nom de fichier, pour ne pas retarder la suite du
traitement. Et de fait, au moins GNU find se comporte ainsi.
- surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un fflush après chaque nom de fichier, pour ne pas retarder la suite du traitement. Et de fait, au moins GNU find se comporte ainsi.
Stephane CHAZELAS
2008-12-16, 11:34(+00), Nicolas George:
Stephane CHAZELAS wrote in message :
- surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un fflush après chaque nom de fichier, pour ne pas retarder la suite du traitement. Et de fait, au moins GNU find se comporte ainsi.
??? Au contraire, faire des fflush sur un pipe est suboptimal, ca causerait plein de context-switch.
ltrace -Se fprintf,fflush montre dans les 200 fprintf et pas un fflush et deux SYS_write de 4096 octets le deuxieme causant un SIGPIPE.
-- Stéphane
2008-12-16, 11:34(+00), Nicolas George:
Stephane CHAZELAS wrote in message
<slrngkf3ve.6t3.stephane.chazelas@spam.is.invalid>:
- surtout, find lui-meme va ecrire morceau par morceau puisque
son stdout n'est pas un terminal, donc ne va probablement rien
ecrire avant d'avoir trouver suffisamment de fichier pour
remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit
faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un
fflush après chaque nom de fichier, pour ne pas retarder la suite du
traitement. Et de fait, au moins GNU find se comporte ainsi.
??? Au contraire, faire des fflush sur un pipe est suboptimal,
ca causerait plein de context-switch.
- surtout, find lui-meme va ecrire morceau par morceau puisque son stdout n'est pas un terminal, donc ne va probablement rien ecrire avant d'avoir trouver suffisamment de fichier pour remplir un "morceau" de 4, 5 ou 8kB (stdio encore, il doit faire des puts() ou printf()).
Ça, ce n'est pas clair du tout. Si je devais écrire un find, je mettrais un fflush après chaque nom de fichier, pour ne pas retarder la suite du traitement. Et de fait, au moins GNU find se comporte ainsi.
??? Au contraire, faire des fflush sur un pipe est suboptimal, ca causerait plein de context-switch.
ltrace -Se fprintf,fflush montre dans les 200 fprintf et pas un fflush et deux SYS_write de 4096 octets le deuxieme causant un SIGPIPE.
-- Stéphane
Antoine
> 2008-12-16, 11:07(+00), Antoine:
Salut,
Quand je fais un: % find / | head
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
D'accord. Et admettons que je veuille regarder comment ceci est implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386), comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et sys.tar.gz ou src.tar.gz ?
-- antoine
> 2008-12-16, 11:07(+00), Antoine:
Salut,
Quand je fais un:
% find / | head
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a
trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va
fermer la sortie du pipe. A partir de ce moment la, des que find va
faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le
tuer.
D'accord. Et admettons que je veuille regarder comment ceci est
implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386),
comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et
sys.tar.gz ou src.tar.gz ?
qu'est-ce qui fait exactement que le find s'arrête ?
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
D'accord. Et admettons que je veuille regarder comment ceci est implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386), comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et sys.tar.gz ou src.tar.gz ?
-- antoine
Stephane Chazelas
2008-12-16, 11:50(+00), Antoine: [...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
D'accord. Et admettons que je veuille regarder comment ceci est implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386), comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et sys.tar.gz ou src.tar.gz ?
[...]
C'est l'appel systeme pipe() appliqué a un fd ouvert sur un pipe. Je ne connais pas les details d'implementation sur OpenBSD, mais l'entry point dans le kernel de l'appel system write(2) sera probablement dans sys.tar.gz. Ensuite, il est probable que ca dispatche vers une fonction/methode "write" specifique aux pipes, donc peut-etre dans un pipe.c. Il y aura probablement un if (pipe.number_of_open_readers == 0) { ...; send_SIGPIPE_to(current_thread); ...; }. Faire un grep SIGPIPE est probablement un bon raccourci.
-- Stéphane
2008-12-16, 11:50(+00), Antoine:
[...]
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a
trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va
fermer la sortie du pipe. A partir de ce moment la, des que find va
faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le
tuer.
D'accord. Et admettons que je veuille regarder comment ceci est
implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386),
comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et
sys.tar.gz ou src.tar.gz ?
[...]
C'est l'appel systeme pipe() appliqué a un fd ouvert sur un
pipe. Je ne connais pas les details d'implementation sur
OpenBSD, mais l'entry point dans le kernel de l'appel system
write(2) sera probablement dans sys.tar.gz. Ensuite, il est
probable que ca dispatche vers une fonction/methode "write"
specifique aux pipes, donc peut-etre dans un pipe.c. Il y aura
probablement un if (pipe.number_of_open_readers == 0) { ...;
send_SIGPIPE_to(current_thread); ...; }. Faire un
grep SIGPIPE est probablement un bon raccourci.
head va faire un ou plusieurs read(0, buf, sizeof(buf)). Des qu'il a trouvé 10 caracteres "NL" dans son input il va se terminer, ce qui va fermer la sortie du pipe. A partir de ce moment la, des que find va faire un write(1, ...), il va se prendre un signal SIGPIPE qui va le tuer.
D'accord. Et admettons que je veuille regarder comment ceci est implémenté par exemple sur mon système ( OpenBSD 4.4 GENERIC#1021 i386), comment je peux trouver, à part un % grep SIGPIPE dans les sources ? Et sys.tar.gz ou src.tar.gz ?
[...]
C'est l'appel systeme pipe() appliqué a un fd ouvert sur un pipe. Je ne connais pas les details d'implementation sur OpenBSD, mais l'entry point dans le kernel de l'appel system write(2) sera probablement dans sys.tar.gz. Ensuite, il est probable que ca dispatche vers une fonction/methode "write" specifique aux pipes, donc peut-etre dans un pipe.c. Il y aura probablement un if (pipe.number_of_open_readers == 0) { ...; send_SIGPIPE_to(current_thread); ...; }. Faire un grep SIGPIPE est probablement un bon raccourci.
-- Stéphane
Nicolas George
Stephane CHAZELAS wrote in message :
??? Au contraire, faire des fflush sur un pipe est suboptimal, ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est rare et que la suite du pipeline est intensive en CPU, c'est un net gain de temps de bufferiser par ligne.
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces programmes orientés traitement de fichiers textes par ligne qui bufferisent par bloc.
Stephane CHAZELAS wrote in message
<slrngkf51b.793.stephane.chazelas@spam.is.invalid>:
??? Au contraire, faire des fflush sur un pipe est suboptimal,
ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est
rare et que la suite du pipeline est intensive en CPU, c'est un net gain de
temps de bufferiser par ligne.
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces
programmes orientés traitement de fichiers textes par ligne qui bufferisent
par bloc.
??? Au contraire, faire des fflush sur un pipe est suboptimal, ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est rare et que la suite du pipeline est intensive en CPU, c'est un net gain de temps de bufferiser par ligne.
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces programmes orientés traitement de fichiers textes par ligne qui bufferisent par bloc.
Vincent Lefevre
Dans l'article <4947f916$0$27345$, Nicolas George <nicolas$ écrit:
Stephane CHAZELAS wrote in message : > ??? Au contraire, faire des fflush sur un pipe est suboptimal, > ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est rare et que la suite du pipeline est intensive en CPU, c'est un net gain de temps de bufferiser par ligne.
Je suis d'accord. Donc en gros, ça dépend du contexte. Dans l'idéal, il serait bien que les fflush soient contrôlés par le temps (voire au niveau du scheduler, mais ce n'est probablement pas possible).
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces programmes orientés traitement de fichiers textes par ligne qui bufferisent par bloc.
Oui, surtout quand on a juste un filtre (e.g. de colorisation) et que la sortie se fera tout de même sur le terminal.
Le problème s'est justement posé avec Subversion (e.g. svn log) et a été corrigé.
De même que la commande après le pipe n'est pas censée bloquer les écritures en ne lisant rien (si bien que le buffer devient plein). C'est le problème de "less"...
Dans l'article <4947f916$0$27345$426a74cc@news.free.fr>,
Nicolas George <nicolas$george@salle-s.org> écrit:
Stephane CHAZELAS wrote in message
<slrngkf51b.793.stephane.chazelas@spam.is.invalid>:
> ??? Au contraire, faire des fflush sur un pipe est suboptimal,
> ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est
rare et que la suite du pipeline est intensive en CPU, c'est un net gain de
temps de bufferiser par ligne.
Je suis d'accord. Donc en gros, ça dépend du contexte. Dans l'idéal,
il serait bien que les fflush soient contrôlés par le temps (voire
au niveau du scheduler, mais ce n'est probablement pas possible).
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces
programmes orientés traitement de fichiers textes par ligne qui
bufferisent par bloc.
Oui, surtout quand on a juste un filtre (e.g. de colorisation) et que
la sortie se fera tout de même sur le terminal.
Le problème s'est justement posé avec Subversion (e.g. svn log) et
a été corrigé.
De même que la commande après le pipe n'est pas censée bloquer les
écritures en ne lisant rien (si bien que le buffer devient plein).
C'est le problème de "less"...
Dans l'article <4947f916$0$27345$, Nicolas George <nicolas$ écrit:
Stephane CHAZELAS wrote in message : > ??? Au contraire, faire des fflush sur un pipe est suboptimal, > ca causerait plein de context-switch.
find a de bonnes chances d'être intensif en I/O. Si la sortie de find est rare et que la suite du pipeline est intensive en CPU, c'est un net gain de temps de bufferiser par ligne.
Je suis d'accord. Donc en gros, ça dépend du contexte. Dans l'idéal, il serait bien que les fflush soient contrôlés par le temps (voire au niveau du scheduler, mais ce n'est probablement pas possible).
Ceci dit, je maintiens ma position de principe : j'ai horreur de ces programmes orientés traitement de fichiers textes par ligne qui bufferisent par bloc.
Oui, surtout quand on a juste un filtre (e.g. de colorisation) et que la sortie se fera tout de même sur le terminal.
Le problème s'est justement posé avec Subversion (e.g. svn log) et a été corrigé.
De même que la commande après le pipe n'est pas censée bloquer les écritures en ne lisant rien (si bien que le buffer devient plein). C'est le problème de "less"...