Sujet : Re: Problèmes bizarres de lecture dans un pipe (en C).
De : om+news (at) *nospam* miakinen.net (Olivier Miakinen)
Groupes : fr.comp.os.linux.configurationDate : 13. Dec 2022, 19:38:02
Autres entêtes
Organisation : There's no cabale
Message-ID : <tnagqb$jpi$1@cabale.usenet-fr.net>
References : 1 2
User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0 SeaMonkey/2.53.1
Bonjour Nicolas, et merci de ta réponse.
Le 13/12/2022 à 19:16, Nicolas George a écrit :
>
1er problème : lorsque le père fait un read() avec un paramètre count
qui est plus grand que PIPE_BUF (c.-à-d. 4096), bien que le fils ait
déjà écrit beaucoup plus d'octets que ça, seuls PIPE_BUF octets sont
retournés par la commande read().
Ça c'est normal, et c'est même souhaitable, ça permet de faire du presque
bloquant qui marche. Personnellement je n'ai pas assez confiance que ce soit
portable, mais en théorie on peu compter dessus. Si tu veux lire une
certaine quantité, tu dois boucler.
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).
2e problème plus grave : lorsque le père fait un read() avec un count
qui est plus *petit* que PIPE_BUF, ce sont bien seulement 'count'
octets qui lui sont retournés, mais au total PIPE_BUF octets sont
effacés du pipe ! Les (PIPE_BUF − count) octets restants sont perdus
et ne seront jamais récupérés par le père lors des read() suivants.
Là, je suis à peu près certain que tu hallucines. Tu peux montrer un strace
sur un exemple minimal ?
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.
253 4956 write(8, "\x0d\x00\x00\x00\x02\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 128) = 128
256 4955 read(7, "\x0d\x00\x00\x00\x02\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 16376) = 128
263 4955 write(6, "\x01\x00\x00\x00\x03\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\xa0\xd7\x23\x01\x00\x00\x00\x00\xff\x22\x40\x00\x00\x00\x00\x00"..., 248) = 248
265 4956 read(5, <unfinished ...>
267 4956 <... read resumed>"\x01\x00\x00\x00\x03\x00\x00\x00\xf8\x00\x00\x00\x00\x00\x00\x00\xa0\xd7\x23\x01\x00\x00\x00\x00\xff\x22\x40\x00\x00\x00\x00\x00"..., 16376) = 248
271 4956 write(8, "\x09\x00\x00\x00\x01\x00\x00\x00\xb8\xce\x0f\x00\x00\x00\x00\x00\xa0\xd7\x23\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 4096) = 4096
278 4955 read(7, "\x09\x00\x00\x00\x01\x00\x00\x00\xb8\xce\x0f\x00\x00\x00\x00\x00\xa0\xd7\x23\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., 16376) = 4096
272 4956 write(8, "\x01\x00\x00\x00\xa0\xc6\xee\x61\x02\x00\x00\x00\x04\x00\x00\x00\x34\x34\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00"..., 4096) = 4096
287 4955 read(7, <unfinished ...>
289 4955 <... read resumed>"\x01\x00\x00\x00\xa0\xc6\xee\x61\x02\x00\x00\x00\x04\x00\x00\x00\x34\x34\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00"..., 12280) = 4096
274 4956 write(8, "\x34\x34\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xc5\xde\xee\x61"..., 4096) = 4096
299 4955 read(7, <unfinished ...>
301 4955 <... read resumed>"\x34\x34\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xc5\xde\xee\x61"..., 8184) = 4096
276 4956 write(8, "\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xad\xf6\xee\x61\x02\x00\x00\x00\x04\x00\x00\x00\x34\x34\x2e\x30\x00\x00\x00\x00"..., 4096) = 4096
313 4955 read(7, <unfinished ...>
315 4955 <... read resumed>"\x28\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xad\xf6\xee\x61\x02\x00\x00\x00\x04\x00\x00\x00\x34\x34\x2e\x30\x00\x00\x00\x00"..., 4088) = 4088
279 4956 write(8, "\x02\x00\x00\x00\x04\x00\x00\x00\x34\x33\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00"..., 4096 <unfinished ...>
282 4956 <... write resumed>) = 4096
332 4955 read(7, <unfinished ...>
334 4955 <... read resumed>"\x02\x00\x00\x00\x04\x00\x00\x00\x34\x33\x2e\x30\x00\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00"..., 16384) = 4096
-- Olivier Miakinen