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 / 509375
Accepted
Rick
Rick
Asked: 2019-03-29 22:57:55 +0800 CST2019-03-29 22:57:55 +0800 CST 2019-03-29 22:57:55 +0800 CST

O que é chamada de sistema interrompida?

  • 772

Estou lendo APUE e o capítulo de Chamadas de Sistema Interrompidas me confunde.

Eu gostaria de escrever minha compreensão com base no livro, por favor, corrija-me.

  1. Uma característica dos sistemas UNIX anteriores era que, se um processo captava um sinal enquanto o processo estava bloqueado em uma chamada de sistema "lenta", a chamada de sistema era interrompida. A chamada do sistema retornou um erro e errnofoi definida como EINTR. Isso foi feito sob a suposição de que, como ocorreu um sinal e o processo o capturou, há uma boa chance de que algo tenha acontecido que deva ativar a chamada de sistema bloqueada.

    Então está dizendo que os sistemas UNIX anteriores têm um recurso: se meu programa usa uma chamada de sistema, ela seria interrompida/parada, se a qualquer momento o programa pegasse um sinal. (O manipulador padrão também conta como uma captura?)

    Por exemplo, se eu tiver uma readchamada de sistema, que lê 10 GB de dados, quando estiver lendo, eu envio qualquer um dos sinais (por exemplo kill -SIGUSR1 pid), então readfalharia e retornaria.


  1. Para evitar que os aplicativos tenham que lidar com chamadas de sistema interrompidas, o 4.2BSD introduziu o reinício automático de certas chamadas de sistema interrompidas. As chamadas do sistema que foram reiniciadas automaticamente são ioctl, read, readv, write, writev, waite waitpid. Como mencionamos, as cinco primeiras dessas funções são interrompidas por um sinal somente se estiverem operando em um dispositivo lento; waite waitpid são sempre interrompidos quando um sinal é captado. Como isso causou um problema para alguns aplicativos que não queriam que a operação fosse reiniciada se ela fosse interrompida, o 4.3BSD permitiu que o processo desabilitasse esse recurso por sinal.

Portanto, antes que a reinicialização automática fosse introduzida, eu tive que lidar sozinho com a chamada do sistema interrompida. Eu preciso escrever código como:

O problema com chamadas de sistema interrompidas é que agora temos que tratar o retorno de erro explicitamente. A sequência de código típica (assumindo uma operação de leitura e assumindo que queremos reiniciar a leitura mesmo que ela seja interrompida) seria:

again:
    if ((n = read(fd, buf, BUFFSIZE)) < 0) {
        if (errno == EINTR)
        goto again; /* just an interrupted system call */
        /* handle other errors */
}

Mas hoje em dia não preciso escrever esse tipo de código, por causa do mecanismo de reinicialização automática .


Então, se meu entendimento estiver correto, o que / por que devo me preocupar com a chamada do sistema interrompida agora ..? Parece que o sistema/SO lida com isso automaticamente.

signals system-calls
  • 2 2 respostas
  • 38423 Views

2 respostas

  • Voted
  1. Best Answer
    mtk
    2019-03-31T12:58:19+08:002019-03-31T12:58:19+08:00

    A interrupção de uma chamada de sistema por um manipulador de sinal ocorre apenas no caso de várias chamadas de sistema de bloqueio e acontece quando a chamada de sistema é interrompida por um manipulador de sinal que foi explicitamente estabelecido pelo programador.

    Além disso, no caso de uma chamada de sistema de bloqueio ser interrompida por um manipulador de sinal, o reinício automático de chamada de sistema é um recurso opcional . Você opta por reiniciar automaticamente as chamadas do sistema especificando o SA_RESTARTsinalizador ao estabelecer o manipulador de sinal. Conforme declarado (por exemplo) na página de manual do Linux signal(7) :

       If  a  signal  handler  is  invoked while a system call or library
       function call is blocked, then either:
    
       * the call is automatically restarted  after  the  signal  handler
         returns; or
    
       * the call fails with the error EINTR.
    
       Which  of  these two behaviors occurs depends on the interface and
       whether or not  the  signal  handler  was  established  using  the
       SA_RESTART  flag (see sigaction(2)). 
    

    Conforme sugerido pela última frase citada acima, mesmo quando você opta por usar esse recurso, ele não funciona para todas as chamadas do sistema, e o conjunto de chamadas do sistema para o qual funciona varia entre as implementações do UNIX. A página de manual do Linux signal(7)observa várias chamadas de sistema que são reiniciadas automaticamente ao usar o SA_RESTARTsinalizador, mas também observa várias chamadas de sistema que nunca são reiniciadas, mesmo se você especificar esse sinalizador ao estabelecer um manipulador, incluindo:

       * "Input" socket interfaces, when a timeout (SO_RCVTIMEO) has been
         set  on  the  socket  using  setsockopt(2):  accept(2), recv(2),
         recvfrom(2), recvmmsg(2) (also with  a  non-NULL  timeout  argu‐
         ment), and recvmsg(2).
    
       * "Output"  socket  interfaces,  when  a timeout (SO_RCVTIMEO) has
         been set on the socket using setsockopt(2): connect(2), send(2),
         sendto(2), and sendmsg(2).
    
       * File   descriptor   multiplexing   interfaces:    epoll_wait(2),
         epoll_pwait(2), poll(2), ppoll(2), select(2), and pselect(2).
    
       * System  V  IPC  interfaces:  msgrcv(2), msgsnd(2), semop(2), and
         semtimedop(2).
    

    Para essas chamadas de sistema, é essencial a reinicialização manual usando um loop da forma descrita em APUE, algo como:

    while ((ret = some_syscall(...)) == -1 && errno == EINTR)
        continue;
    if (ret == -1)
        /* Handle error */ ;
    
    • 9
  2. Uncle Billy
    2019-03-30T00:29:25+08:002019-03-30T00:29:25+08:00

    [Eu não li essa coisa de APUE, mas as coisas que você está citando não parecem muito boas]

    se meu programa usar uma chamada de sistema, ele será interrompido/parado, se a qualquer momento o programa pegar um sinal.

    Não qualquer chamada de sistema. Apenas algumas chamadas do sistema podem ser interrompidas.

    (O manipulador padrão também conta como uma captura?)

    Não.

    Por exemplo, se eu tiver uma chamada de sistema de leitura, que lê dados de 10 GB, quando estiver lendo, eu envio qualquer um dos sinais (por exemplo, kill -SIGUSR1 pid), então a leitura falharia e retornaria.

    Seu read() de 10 GB só retornará com EINTR se tiver sido interrompido antes de poder ler até mesmo um único byte ; caso contrário, retornará a quantidade de dados que já havia lido (short read = sucesso, errno não relevante).

    [isso não foi explicado no dupe vinculado]

    Então, se meu entendimento estiver correto, o que / por que devo me preocupar com a chamada do sistema interrompida agora ..? Parece que o sistema/SO lida com isso automaticamente.

    Porque você pode querer fazer algo ao receber um sinal e não pode fazer muito de um manipulador de sinal; qualquer coisa usando malloc() ou stdio (mesmo printf()) está fora de questão. Então você tem que lidar com as interrupções no loop principal do programa, e para poder fazer isso, você deve quebrar de alguma forma um read() de bloqueio (um read() pode bloquear mesmo depois que um poll() retornar um fd como pronto para leitura).

    [isso também foi explicado no dupe vinculado]

    • 3

relate perguntas

  • 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?

  • O uso da função system () dentro do código C ++ é uma maneira rápida de usar códigos-fonte? [fechado]

  • bit de modo kernel

  • Necessidade de algumas chamadas de sistema

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