Quais são as garantias para gravações simultâneas em um pipe nomeado?

32

Por exemplo, eu criei um pipe nomeado como o seguinte:

mknod myPipe p

E eu li a partir de algum processo (por exemplo, algum servidor). Por exemplo, usei tail:

tail -f myPipe

Se vários processos do cliente gravarem algumas mensagens nele (por exemplo, echo "msg" >> myPipehá alguma chance de que as mensagens sejam intercaladas, desta forma:

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

Ou o processo de gravação no pipe nomeado é atômico?

Rogach
fonte

Respostas:

29

Depende do quanto cada processo está gravando (assumindo que seu sistema operacional seja compatível com POSIX a esse respeito). De write():

As solicitações de gravação para um canal ou FIFO devem ser tratadas da mesma maneira que um arquivo regular, com as seguintes exceções:
[...]

  • Os pedidos de gravação de bytes {PIPE_BUF} ou menos não devem ser intercalados com dados de outros processos que executam gravações no mesmo canal. Gravações maiores que {PIPE_BUF} bytes podem ter dados intercalados, em limites arbitrários, com gravações de outros processos, independentemente de o sinalizador O_NONBLOCK dos sinalizadores de status do arquivo estar definido ou não.

Também na seção Justificativa sobre tubos e FIFOs:

  • Atômico / não atômico : Uma gravação é atômica se toda a quantidade gravada em uma operação não for intercalada com dados de qualquer outro processo. Isso é útil quando há vários gravadores enviando dados para um único leitor. Os aplicativos precisam saber qual o tamanho de uma solicitação de gravação que pode ser executada atomicamente. Esse valor máximo é chamado {PIPE_BUF}. Este volume do POSIX.1-2008 não indica se os pedidos de gravação para mais de {PIPE_BUF} bytes são atômicos, mas requer que gravações de {PIPE_BUF} ou menos bytes sejam atômicas.

O valor se PIPE_BUFé definido por cada implementação, mas o mínimo é 512 bytes (consulte limits.h). No Linux, são 4096 bytes (consulte pipe(7)).

Esteira
fonte
5
PIPE_BUF é, a propósito, garantido que seja pelo menos 512. Observe que você também precisa garantir que seu processo realmente grave cada linha nele em uma única chamada de gravação. A ativação do buffer de linha ( setvbuf(stdout, NULL, _IOLBF,512)) fará isso sem exigir o uso de funções de baixo nível.
Random832
Aqui está uma tabela de observados PIPE_BUFvalores em sistemas Unix comuns: ar.to/notes/posix#pipe-buf
Arto Bendiken
Eu não entendo como soquetes podem ser multiplexados ... mas pipes nomeados não podem ?? tudo no unix é apenas um arquivo, certo? lulz
Alexander Mills
@AlexanderMills: Eu não entendo o seu comentário
Mat
1
@AlexanderMills: não, esse é o valor mínimo #
Mat #