usando fifo para daemons

0

Enquanto estudava na programação de rede Unix do livro de Richard Stevens, Eu me deparei com as seguintes linhas que falam sobre o uso do FIFO entre um cliente e um servidor.

Client processes are started and they open the FIFO for writing ,write their request, and exit. What happens is the read returns zero to the daemon every time a client process terminates. the daemon then has to open the FIFO again(for read only) and it waits here until a client process opens it for writing.

Eu não entendi a última linha. Por que o processo do servidor tem que abrir o FIFO novamente, ele só precisa ler novamente depois que um processo do cliente tiver escrito nele, certo?

    
por dhruv gupta 19.06.2018 / 18:38

1 resposta

0

Why does the server process have to open FIFO again, it just has to read again after a client process has written into it, right?

Interessante, vamos tentar sua sugestão. Os seguintes resultados foram gerados no Linux 4.9.0-6-amd64 (kernel do Ubuntu Linux).

$ mkfifo t
$ (cat; cat) < t &    # run a "server" as a background job
[1] 4856
$ echo 1 > t
1
[1]+  Done                    ( cat; cat ) < t

Não funcionou como queríamos. O primeiro cat lê EOF como esperado e, em seguida, sai. O problema é que o segundo cat também lê EOF imediatamente, e assim nosso "servidor" termina. Não é possível esperar por um novo cliente (sem chamar repetidamente read () e desperdiçar tempo de CPU).

Se você souber como manipular descritores de arquivos (FDs) no shell, podemos ver isso de outra forma para ajudar a confirmar isso.

$ echo 1 > t &
$ exec 3 < t    # open "t" for reading, as FD 3.
$ cat <&3
1
[1]+  Done                    echo 1 > t
$ cat <&3
$

$ echo 2 > t &
[1] 5102
$ cat <&3
2
[1]+  Done                    echo 2 > t
$ cat <&3
$ 

A resposta é que o que a recapitulação do fifo alcança, é impedir que alguém o abra para escrever. Sem essa etapa, todas as chamadas subsequentes para open() do fifo retornarão imediatamente 0 (EOF).

Quando notei isso, imaginei como read() funciona. Este programa emula o antigo systemd-initctl fifo sob systemd. (Aviso: não é muito fácil testar isso; não vou me preocupar em documentar como). A resposta é que o systemd-initctl abre o fifo para leitura e escrita. (Tecnicamente é o systemd que abre o fifo, conforme especificado pelo systemd-initctl.socket, e passa para o systemd-initctl). Abrir um fifo para ler e escrever simultaneamente é um recurso específico do Linux. Mas ao fazer isso, o systemd está implementando o mesmo truque que Stevens menciona a seguir:

To avoid this, a use­ful technique is for the daemon to open the FIFO two times- once for reading and once for writing. The file descriptor returned for reading is used to read the client requests , and the file descriptor for writing is never used. By having the FIFO always open for writing (as long as the daemon process exists) the reads do not return an EOF, but wait for the next client request.

    
por 19.06.2018 / 22:11