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 / 531171
Accepted
Lassi
Lassi
Asked: 2019-07-21 06:00:10 +0800 CST2019-07-21 06:00:10 +0800 CST 2019-07-21 06:00:10 +0800 CST

Por que fork() foi projetado para retornar um descritor de arquivo?

  • 772

Em sua página da web sobre o truque do tubo automático , Dan Bernstein explica uma condição de corrida select()e sinaliza, oferece uma solução alternativa e conclui que

Claro, a Coisa Certa seria ter fork()retornado um descritor de arquivo, não um ID de processo.

O que ele quer dizer com isso - é algo sobre poder select()nos processos filho manipular suas mudanças de estado em vez de ter que usar um manipulador de sinal para ser notificado dessas mudanças de estado?

signals file-descriptors
  • 4 4 respostas
  • 3008 Views

4 respostas

  • Voted
  1. Best Answer
    ilkkachu
    2019-07-21T06:12:28+08:002019-07-21T06:12:28+08:00

    O problema está descrito lá na sua fonte, select()deve ser interrompido por sinais como SIGCHLD, mas em alguns casos não funciona tão bem. Portanto, a solução alternativa é fazer com que o sinal seja gravado em um pipe, que é então observado por select(). Observar os descritores de arquivos select()é para isso, então isso resolve o problema.

    A solução alternativa basicamente transforma o evento de sinal em um evento de descritor de arquivo. Se fork()apenas retornasse um fd em primeiro lugar, a solução alternativa não seria necessária, pois esse fd poderia presumivelmente ser usado diretamente com select().

    Então, sim, sua descrição no último parágrafo parece certa para mim.


    Outra razão pela qual um fd (ou algum outro tipo de identificador de kernel) seria melhor do que um número de identificação de processo simples, é que os PIDs podem ser reutilizados após a morte do processo. Isso pode ser um problema em alguns casos ao enviar sinais para processos, pode não ser possível saber com certeza se o processo é aquele que você pensa que é, e não outro reutilizando o mesmo PID. (Embora eu ache que isso não deve ser um problema ao enviar sinais para um processo filho, já que o pai precisa executar wait()no filho para que seu PID seja liberado.)

    • 13
  2. user732
    2019-07-21T06:14:01+08:002019-07-21T06:14:01+08:00

    Bernstein não dá muito contexto para esta observação "Coisa certa", mas vou arriscar um palpite: ter fork(2) retornar um PID é inconsistente com open(2), creat(2) etc retornando descritores de arquivo. O resto do sistema Unix poderia ter feito a manipulação do processo com um descritor de arquivo representando um processo, em vez de um PID. Existe uma chamada de sistema signalfd(2) , que permite uma interação um pouco melhor entre sinais e descritores de arquivo, e mostra que um descritor de arquivo representando um processo poderia funcionar.

    • 8
  3. mosvy
    2019-07-21T15:35:00+08:002019-07-21T15:35:00+08:00

    É apenas uma reflexão sobre as linhas de "seria ótimo se o Unix fosse projetado de forma diferente do que é".

    O problema com os PIDs é que eles vivem em um namespace global onde podem ser reutilizados para outro processo, e seria bom se fork()retornasse no pai algum tipo de handle que garantisse sempre se referir ao processo filho, e que poderia passar para outros processos via herança ou soquetes unix / SCM_RIGHTS[1].

    Veja também a discussão aqui para um esforço recente para "consertar" isso no Linux, incluindo a adição de um sinalizador ao clone()qual fará com que ele retorne um pid-fd em vez de um PID.

    Mas mesmo assim, isso não eliminaria a necessidade daquele hack de auto-pipe [2] ou interfaces melhores, já que os sinais que notificam um processo pai sobre o estado de um filho não são os únicos que você gostaria de manipular no loop principal do programa. Infelizmente, coisas como epoll(7) + signalfd(2)no Linux ou kqueue(2)no BSD não são padrão - a única interface padrão (mas não suportada em sistemas mais antigos) é muito inferior pselect(2).

    [1] Impedir que o PID seja reciclado no momento em que o waitpid()syscall retornar e seu valor de retorno for usado provavelmente poderia ser alcançado em sistemas mais novos usando waitid(.., WNOWAIT)em vez disso.

    [2] Eu não comentaria sobre a afirmação de DJ Bernstein que ele inventou (desculpe a apófase ;-)).

    • 8
  4. mtk
    2020-02-19T03:34:12+08:002020-02-19T03:34:12+08:00

    O ponto é que existem muitos programas que operam um modelo de estilo de loop de eventos baseado em descritores de arquivos de monitoramento com select(2) / poll(2) / epoll(7) . Mas havia vários eventos que historicamente não notificavam usando descritores de arquivo - entre eles a transição de estado do processo (por exemplo, encerramento) de um processo filho. A necessidade de lidar separadamente com esses outros eventos (que incluem expirações de temporizadores, sinais e eventos de sincronização, como alterações de semáforo) complicou a programação do modelo de loop de eventos.

    Nos últimos anos, o desenvolvimento do Linux vem resolvendo esse problema, de modo que hoje em dia temos signalfd(2) (torna os sinais legíveis a partir de um descritor de arquivo), eventfd(2) (uma primitiva de sincronização cujo identificador é um descritor de arquivo) , e timerfd_create(2) (criam temporizadores que notificam por meio de um descritor de arquivo), todos os quais produzem descritores de arquivo que podem ser alimentados para select(2) / poll(2) / epoll(7) .

    E, finalmente, versões recentes do Linux adicionaram o conceito de um identificador para um processo como descritor de arquivo. O CLONE_PIDFDsinalizador de clone3() pode ser usado para criar um processo filho para o qual um descritor de arquivo como identificador é retornado. O descritor de arquivo também pode ser alimentado em select(2) / poll(2) / epoll(7) e indica como legível se o processo filho termina.

    • 1

relate perguntas

  • O manipulador de armadilhas não está funcionando?

  • Por que os descritores de arquivo são compartilhados entre processos bifurcados?

  • Manipulando o SIGALRM de duas maneiras diferentes

  • Por que o SIGTSTP existe quando já existe o SIGSTOP?

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

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

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

    • 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

    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
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • 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
    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

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