Path: ...!feeds.phibee-telecom.net!2.eu.feeder.erje.net!feeder.erje.net!proxad.net!feeder1-2.proxad.net!usenet-fr.net!.POSTED!not-for-mail From: Olivier Miakinen Newsgroups: fr.comp.os.linux.configuration Subject: =?UTF-8?Q?Re:_Probl=c3=a8mes_bizarres_de_lecture_dans_un_pipe_=28en?= =?UTF-8?Q?_C=29.?= Date: Wed, 14 Dec 2022 11:25:26 +0100 Organization: There's no cabale Lines: 72 Message-ID: References: <6398c186$0$24817$426a74cc@news.free.fr> <63999974$0$3182$426a74cc@news.free.fr> NNTP-Posting-Host: 200.89.28.93.rev.sfr.net Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: cabale.usenet-fr.net 1671013526 48820 93.28.89.200 (14 Dec 2022 10:25:26 GMT) X-Complaints-To: abuse@usenet-fr.net NNTP-Posting-Date: Wed, 14 Dec 2022 10:25:26 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0 SeaMonkey/2.49.4 In-Reply-To: <63999974$0$3182$426a74cc@news.free.fr> Bytes: 4716 Le 14/12/2022 10:37, Nicolas George a écrit : > Olivier Miakinen , dans le message , > a écrit : >> Sur d'autres machines avec le même programme, quand on dit qu'on est >> capable de lire 10 000 octets et qu'il y en a déjà 30 000 en attente, >> le read retourne bien 10 000 octets. Je ne vois pas pourquoi il serait >> souhaitable de n'en retourner que 4 096 si tout le monde est d'accord >> pour 10 000. >> >> Ce qui n'empêche pas de boucler, bien sûr, pour récupérer les 20 000 >> octets qui restent (voire plus lorsque le fils continue à fournir). > > Effectivement, j'ai lu un peu trop vite. Ce que tu décris est un > comportement acceptable mais pas souhaitable. > > Mais ça ne correspond pas non plus à ce que j'observe, avec : > > { strace -Tttt -o /dev/pts/14 perl -e '$| = 1; syswrite STDOUT, "X" x 30000'; sleep 2 } | strace -Tttt -o /dev/pts/15 perl -e 'sysread STDIN, $buf, 40000' > > … je vois : > > 1671009300.373032 write(1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 30000) = 30000 <0.000018> > 1671009300.372976 read(0, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 40000) = 30000 <0.000089> > > Donc le read se satisfait des 30000 sans attendre les 40000 (souhaitable), > mais lit quand même plus que 4096. Nous sommes d'accord. C'est le comportement que je constate sur toutes les machines autres que celle du client : on retourne MIN(demandé, présent), alors que sur la machine du client c'est MIN(demandé, présent, 4096). >> Un exemple minimal, pas vraiment, mais oui je peux montrer un strace. >> En fait je peux même montrer une analyse minimale d'un strace qui >> n'était pas du tout minimal. >> >> Dans les traces qui suivent, j'ai supprimé tout que ce n'est pas un >> write(8, ...) du fils ou un read(7, ...) du père, et j'ai réordonné >> les lignes pour que chaque read() suive le write() correspondant, >> mais j'ai laissé le numéro de ligne de la trace d'origine. On voit >> donc en premier le numéro de ligne (de 253 à 334), en second le >> PID (4955 pour le père, 4956 pour le fils), puis le read ou le >> write avec les premiers octets en hexadécimal. > > Mais que vois-tu de suspect dans ce strace ? Regarde les lignes 276 et 313, puis 279 et 332 : 276 4956 write(8, "\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00"..., 4096) = 4096 313 4955 read(7, "\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00"..., 4088) = 4088 279 4956 write(8, "\x02\x00\x00\x00\x04\x00\x00\x00\x34\x33"..., 4096) = 4096 332 4955 read(7, "\x02\x00\x00\x00\x04\x00\x00\x00\x34\x33"..., 16384) = 4096 > Je fais un essai de mon côté : > > strace -Tttt -o /dev/pts/14 perl -e '$| = 1; syswrite STDOUT, "X" x 4096 . "Y" x 4096' | strace -Tttt -o /dev/pts/15 perl -e 'sysread STDIN, $buf, 4090; sysread STDIN, $buf, 4000;' > > 1671010596.009083 write(1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 8192) = 8192 <0.000011> > 1671010596.009071 read(0, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"..., 4090) = 4090 <0.000027> > 1671010596.009115 read(0, "XXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYY"..., 4000) = 4000 <0.000008> > > On voit bien que le 2e read a reçu les 6 X qui restaient. Dans les lignes 276 et 313, le fils a envoyé 4096 octets dont seuls 4088 sont reçus par le père. Le read suivant devrait donc commencer par 8 octets qu'on ne voit pas tracés, puis les octets tracés du write suivant. Or ces 8 octets ne sont pas là : le read en 332 reçoit uniquement les octets envoyés dans le write en 279. -- Olivier Miakinen