Quelles sont les garanties pour les écritures simultanées dans un canal nommé?

32

Par exemple, j'ai créé un canal nommé comme suit:

mknod myPipe p

Et je l'ai lu à partir de certains processus (par exemple, un serveur). Par exemple, j'ai utilisé tail:

tail -f myPipe

Si plusieurs processus clients y écrivent des messages (par exemple, echo "msg" >> myPipey a-t-il un risque que les messages soient entrelacés, comme ceci:

 <beginning of message1><message2><ending of message1>

Ou bien le processus d’écriture dans un canal nommé est-il atomique?

Rogach
la source

Réponses:

29

Cela dépend de la quantité d'écriture de chaque processus (en supposant que votre système d'exploitation est compatible POSIX à cet égard). De write():

Les demandes d'écriture dans un tube ou une FIFO doivent être traitées de la même manière qu'un fichier normal, à l'exception des cas suivants:
[...]

  • Les demandes d'écriture de {PIPE_BUF} octets ou moins ne doivent pas être entrelacées avec les données d'autres processus effectuant des écritures sur le même canal. Les écritures de plus de {PIPE_BUF} octets peuvent avoir des données entrelacées, sur des limites arbitraires, avec des écritures d'autres processus, que l'indicateur O_NONBLOCK des indicateurs d'état du fichier soit défini ou non.

Également dans la section Justification concernant les tuyaux et les FIFO:

  • Atomique / non atomique : Une écriture est atomique si la totalité de la quantité écrite en une opération n'est pas entrelacée avec les données d'un autre processus. Ceci est utile lorsque plusieurs rédacteurs envoient des données à un seul lecteur. Les applications ont besoin de savoir quelle taille une demande d'écriture peut être effectuée de manière atomique. Ce maximum s'appelle {PIPE_BUF}. Ce volume de POSIX.1-2008 n'indique pas si les demandes d'écriture de plus de {PIPE_BUF} octets sont atomiques, mais nécessite que les écritures de {PIPE_BUF} ou moins soient atomiques.

La valeur if PIPE_BUFest définie par chaque implémentation, mais la valeur minimale est 512 octets (voir limits.h). Sous Linux, il s’agit de 4096 octets (voir pipe(7)).

Tapis
la source
5
Soit dit en passant, PIPE_BUF doit être au moins égal à 512. Notez que vous devez également vous assurer que votre processus y écrit réellement chaque ligne lors d'un seul appel en écriture. Activer la mise en tampon de ligne ( setvbuf(stdout, NULL, _IOLBF,512)) fera cela sans vous obliger à utiliser des fonctions de bas niveau.
Random832
Voici un tableau des PIPE_BUFvaleurs observées sur les systèmes Unix courants: ar.to/notes/posix#pipe-buf
Arto Bendiken
Je ne comprends pas comment les sockets peuvent être multiplexés ... mais les pipes nommées ne peuvent pas ?? tout sur unix est juste un fichier non? lulz
Alexander Mills
@AlexanderMills: je ne comprends pas votre commentaire
Mat
1
@AlexanderMills: non, c'est la valeur minimale
Mat le