Como o título sugere, tente os seguintes comandos shell:
mkfifo /tmp/test.pipe
ls -1 /tmp > /tmp/test.pipe &
rm /tmp/test.pipe
mkfifo /tmp/test.pipe
cat /tmp/test.pipe &
jobs
O comando ls
é apenas um exemplo e pode ser qualquer processo que queira gravar no pipe nomeado. O ponto aqui é que o processo bloqueará a tentativa de abrir o pipe para gravação. Agora, outro processo vem e remove o tubo. Um novo canal com o mesmo nome é criado e o processo cat
(ou seja, qualquer processo que tente abri-lo para leitura) bloqueará a espera de outro processo para gravar no novo canal com o mesmo nome. Ambos os processos estão aguardando sua conexão de tubulação. Isso pode ser verificado listando o background jobs
.
Não estou muito preocupado com o bloqueio cat
(ou qualquer processo que esteja tentando ler do canal), porque, na verdade, o processo de leitura do pipe é, na verdade, o primeiro a substituí-lo. Na verdade, não me importo com os processos de leitura. O cat
serve apenas meu exemplo para provar que, de fato, ambos os processos se referem ao mesmo nome do arquivo pipe, mas estão obviamente usando instâncias de pipe distintas. No entanto, observe que esse exemplo de deadlock também seria bloqueado no caso inverso, ou seja, um processo de leitura seria bloqueado para sempre se o pipe fosse excluído sem nunca ter sido aberto para gravação.
Meu foco está no processo de gravação de bloqueio (o ls
no meu exemplo). Ele nunca tem a chance de perceber que o pipe original para o qual ele está tentando gravar foi substituído por um novo com o mesmo nome.
Existe alguma maneira do Linux para identificar tais situações, ou seja, uma situação em que um processo bloqueia a gravação de acesso a um pipe nomeado que não existe mais? Você pode assumir privilégios de root e que eu Conhecer os PIDs de todos os processos envolvidos. Em particular, conheço o processo de escrita que pode ou não ter ocorrido em tal situação. No entanto, eu não sei (que é o que eu quero descobrir), se o processo realmente se deparou com esse problema ou não , para que eu possa finalizá-lo. Como posso encontrar processos que estão bloqueando o acesso a um pipe nomeado que não existe fisicamente no sistema de arquivos?
Aparentemente, ls /proc/<PID>/fd
não lista o descritor de arquivo para o acesso do processo a qualquer canal, exceto quando ambas as extremidades de um pipe estão conectadas, ou seja, ls /proc/<PID>/fd
listará os descritores de arquivo em um canal apenas para ambos os processos após a chamada do sistema ter retornado com sucesso em ambas as suas extremidades. Como no meu exemplo há dois pipes half-connected distintos com o mesmo nome, nenhum deles é listado para nenhum dos processos.