AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 433345
Accepted
Naïm Favier
Naïm Favier
Asked: 2018-03-25 15:53:25 +0800 CST2018-03-25 15:53:25 +0800 CST 2018-03-25 15:53:25 +0800 CST

Em que condições exatamente o SIGPIPE acontece?

  • 772

Digamos que temos um pipe nomeado chamado fifo, e estamos lendo e escrevendo nele de dois shells diferentes. Considere estes dois exemplos:

shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>

shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>

Não consigo entender o que acontece nesses exemplos e, em particular, por que tentar escrever 'bar' no canal no primeiro exemplo resulta em uma chamada de bloqueio, enquanto no segundo exemplo aciona um SIGPIPE.

Entendo que, no primeiro caso, dois processos separados gravam no pipe e, portanto, ele é aberto duas vezes, enquanto no segundo caso é aberto apenas uma vez por um único processo e gravado duas vezes, com o processo lendo o pipe sendo morto nesse meio tempo. O que não entendo é como isso afeta o comportamento do write.

A pipe(7)página de manual afirma:

Se todos os descritores de arquivo referentes ao final de leitura de um pipe tiverem sido fechados, então uma gravação (2) fará com que um sinal SIGPIPE seja gerado para o processo de chamada.

Esta condição não parece clara para mim. Um descritor de arquivo fechado simplesmente deixa de ser um descritor de arquivo, certo? Como dizer " a extremidade de leitura do tubo foi fechada " difere de " a extremidade de leitura do tubo não está aberta "?

Espero que minha pergunta tenha sido clara o suficiente. A propósito, se você pudesse sugerir dicas para entender em detalhes o funcionamento dos pipes Unix em relação a open, e operações close, eu agradeceria muito.readwrite

pipe signals
  • 2 2 respostas
  • 18941 Views

2 respostas

  • Voted
  1. Best Answer
    A.B
    2018-03-25T16:51:20+08:002018-03-25T16:51:20+08:00

    Seu exemplo está usando a fifonot a pipe, então está sujeito a fifo(7). pipe(7)também conta:

    Um FIFO (abreviação de First In First Out) tem um nome dentro do sistema de arquivos (criado usando mkfifo(3)) e é aberto usando open(2). Qualquer processo pode abrir um FIFO, desde que as permissões do arquivo o permitam. O final de leitura é aberto usando o sinalizador O_RDONLY; o final da gravação é aberto usando o sinalizador O_WRONLY. Veja fifo(7) para mais detalhes. Observação: embora os FIFOs tenham um nome de caminho no sistema de arquivos, a E/S nos FIFOs não envolve operações no dispositivo subjacente (se houver).

    E/S em pipes e FIFOs
    A única diferença entre pipes e FIFOs é a maneira como são criados e abertos. Uma vez que essas tarefas tenham sido realizadas, a E/S em pipes e FIFOs tem exatamente a mesma semântica.

    Então agora de fifo(7):

    O kernel mantém exatamente um objeto pipe para cada arquivo especial FIFO que é aberto por pelo menos um processo. O FIFO deve ser aberto em ambas as extremidades (leitura e escrita) antes que os dados possam ser passados. Normalmente, abrindo os blocos FIFO até que a outra extremidade seja aberta também.

    Portanto, antes que ambas as extremidades (aqui significando que há pelo menos um leitor e um gravador) sejam abertas, escreva blocos de acordo com fifo(7). Depois que ambas as extremidades foram abertas e, em seguida, (as) extremidades de leitura fechadas, a gravação gera SIGPIPE conforme pipe(7).

    Para um exemplo de uso de pipe (não fifo), veja a seção de exemplo depipe(2) : envolve pipe() (sem open(), já que pipe() realmente criou o par de pipes aberto), close(), read() write() e fork () (quase sempre há um fork () ao usar um pipe).

    A maneira mais simples de lidar com o SIGPIPE a partir do seu próprio código C, se você não quiser que ele morra ao gravar em um fifo, seria chamá signal(SIGPIPE, SIG_IGN);-lo e manipulá-lo verificando o errno EPIPEapós cada gravação ().

    • 12
  2. Mumtaz Ahmad
    2018-03-26T03:02:50+08:002018-03-26T03:02:50+08:00

    A gravação em um pipe ou FIFO que não possui um processo de leitura é tratada como uma condição de erro; ele gera um sinal SIGPIPE e falha com o código de erro EPIPE se o sinal for manipulado ou bloqueado.

    • 2

relate perguntas

  • Qual número de 1 a 64 é o número do sinal de depuração?

  • Passe o identificador para o pipeline stdin down

  • Como canalizar um comando bash e manter Ctrl + C funcionando?

  • Por que canalizar `mysql` para 'tail' altera o formato de saída?

  • ordem de substituição de processos `te` e `bash`

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve