Manipulação de entrada e saída

Este tópico fornece uma introdução às considerações de programação para manipulação de entrada e saída e as subroutines de manipulação de entrada e saída (E/S).

As subroutines da biblioteca de E/S podem enviar dados para ou a partir de dispositivos ou arquivos. O sistema trata dispositivos como se fossem arquivos de E/S. Por exemplo, você também deve abrir e fechar um dispositivo assim como você faz um arquivo.

Algumas das subroutines usam entrada padrão e saída padrão como seus canais de I/O. Para a maioria das subroutines, no entanto, é possível especificar um arquivo diferente para a origem ou destino da transferência de dados. Para algumas subroutines, você pode usar um ponteiro de arquivo para uma estrutura que contém o nome do arquivo; para outros, você pode usar um descritor de arquivo (ou seja, o inteiro positivo atribuído ao arquivo quando ele for aberto).

As sub-rotinas de E/S armazenadas na Biblioteca C (libc.a) fornecem E/S de fluxo. Para acessar essas sub-rotinas de E/S de fluxo, deve-se incluir o arquivo stdio.h usando a instrução a seguir:
#include <stdio.h>

Algumas subroutines da biblioteca de E/S são macros definidas em um arquivo de cabeçalho e alguns são módulos de objetos de funções. Em muitos casos, a biblioteca contém uma macro e uma função que fazem o mesmo tipo de operação. Considere o seguinte ao decidir se deve utilizar a macro ou a função:

  • Não é possível configurar um quebra-quebra para uma macro usando o programa dbx .
  • As macros geralmente são mais rápidas do que suas funções equivalentes porque o pré-processador substitui as macros por linhas reais de código no programa.
  • Macros resultam em código de objeto maior após serem compilados.
  • As funções podem ter efeitos colaterais para evitar.

Os arquivos, comandos e subroutines utilizados na manipulação de E/S fornecem as seguintes interfaces:

Baixo nível
A interface de baixo nível fornece funções básicas abertas e próximas para arquivos e dispositivos.
Fluxo
A interface stream fornece E/S de leitura e gravação para tubos e FIFOs.
Terminal
A interface do terminal fornece saída formatada e buffering.
Assíncrono
A interface assíncrona fornece E/S e processamento simultâneos.
Idioma de Entrada
A interface de idioma de entrada usa os comandos lex e yacc para gerar um analisador lexical e um programa parser para interpretação de E/S.

Interfaces de E/S de baixo nível

As interfaces de E/S de baixo nível são pontos de entrada direta em um kernel, fornecendo funções como abrir arquivos, ler para e gravar a partir de arquivos, e fechar arquivos.

O comando line fornece a interface que permite que uma linha a partir de entrada padrão seja lida, e as subroutines a seguir fornecem outras funções de E/S de baixo nível:

aberto, openx ou creat
Preparar um arquivo, ou outro objeto de caminho, para leitura e escrita por meio de um descritor de arquivo designado
read, readx, readv ou readvx
Ler a partir de um descritor de arquivo aberto
escrever, writex, writev ou writevx
Escreva para um descritor de arquivo aberto
Fechar
Abdicar de um descritor de arquivo

As subroutines open e creat configuram entradas em três tabelas do sistema. Um descritor de arquivo indexa a primeira tabela, que funciona como uma área de dados por processo que pode ser acessada por subroutines de leitura e gravação. Cada entrada nesta tabela tem um ponteiro para uma entrada correspondente na segunda tabela.

A segunda tabela é um banco de dados por sistema, ou tabela de arquivos, que permite que um arquivo aberto seja compartilhado entre vários processos. As entradas nesta tabela indicam se o arquivo estava aberto para leitura, escrita ou como um tubo, e quando o arquivo foi fechado. Há também um deslocamento para indicar onde ocorrerá a próxima leitura ou gravação e um ponteiro final para indicar a entrada para a terceira tabela, que contém uma cópia do i-node do arquivo.

A tabela de arquivos contém entradas para cada instância de um subroutine de open ou create no arquivo, mas a tabela i-node contém apenas uma entrada para cada arquivo.

Nota: Enquanto processam uma subroutine aberta ou creat para um arquivo especial, o sistema sempre chama a subroutine aberta do dispositivo para permitir qualquer processamento especial (como rebobinar uma fita ou ligar um lead-ready-ready modem lead). No entanto, o sistema usa a subroutina fechar apenas quando o último processo fecha o arquivo (ou seja, quando a entrada da tabela i-node é dealocada). Isso significa que um dispositivo não pode manter ou depender de uma contagem de seus usuários a menos que um dispositivo de uso exclusivo (que impeça que um dispositivo seja reaberto antes de seu fechado) seja implementado.

Quando ocorre uma operação de leitura ou gravação, os argumentos do usuário e a entrada da tabela de arquivos são utilizados para configurar as seguintes variáveis:

  • Endereço do usuário da área de destino de E/S
  • Contagem de bytes para a transferência
  • Localização atual no arquivo

Se o arquivo referido for um arquivo especial de tipo de caractere, a subroutine de leitura ou gravação apropriada é chamada para transferir dados, bem como atualizar a contagem e a localização atual. Caso contrário, o local atual é usado para calcular um número de bloqueio lógico no arquivo.

Se o arquivo for um arquivo ordinário, o número do bloco lógico deve ser mapeado para um número de bloco físico. Um arquivo especial do tipo bloco não precisa ser mapeado. O número do bloco físico resultante é usado para ler ou escrever o dispositivo apropriado.

Os drivers de dispositivos de blocos podem fornecer a capacidade de transferir informações diretamente entre a imagem principal do usuário e o dispositivo em tamanhos de blocos tão grandes quanto os pedidos de chamada sem usar buffers. O método envolve a configuração de um arquivo especial de tipo de caractere correspondente ao dispositivo bruto e fornecer subroutines de leitura e gravação para criar um cabeçalho de buffer privado e não compartilhado com as informações apropriadas. Podem ser fornecidas subroutines abertas e próximas podem ser fornecidas, e uma subroutina de função especial pode ser chamada para fita magnética.

interfaces de E/S de fluxo

As interfaces de E/S de stream fornecem dados como um fluxo de bytes que não é interpretado pelo sistema, que oferece uma implementação mais eficiente para protocolos de rede do que o processamento de E/S de caracteres. Nenhum limite de registro existe ao ler e escrever usando E/S de stream. Por exemplo, um processo de leitura de 100 bytes de um tubo não pode determinar se o processo que escreveu os dados no pipe fez uma única gravação de 100 bytes, ou duas gravações de 50 bytes, ou mesmo se a década de 100 bytes veio de dois processos diferentes.

Os I/Os de Fluxo podem ser canos ou FIFOs (primo-entrada, arquivos de primeiro para fora). Os FIFOs são semelhantes a tubulações porque permitem que os dados fluam apenas de uma maneira (esquerda para a direita). No entanto, um FIFO pode receber um nome e pode ser acessado por processos não relacionados, ao contrário de uma tubulação. Os FIFOs às vezes são chamados de pipes nomeados. Por ter um nome, um FIFO pode ser aberto usando a subroutine de E/S padrão fopen . Para abrir um pipe, você deve chamar o subroutine pipe , que retorna um descritor de arquivo, e a subroutine padrão de E/S fdopen para associar um descritor de arquivo aberto a um fluxo de E/S padrão.

Nota: Fluxo de interfaces de E/S de fluxo de E/S em nível de usuário e não pode gravar os dados até que o fclose ou fflush Subroutine seja executado, o que pode levar a resultados inesperados quando misturados com E/S de arquivo como leitura () ou gravação ().

As interfaces de E/S de Fluxo são acessadas através das seguintes subroutines e macros:

fperto
Fecha um fluxo
feof, ferror, clearerr ou fileno
Verificar o status de um fluxo
descarga
Escreva todos os caracteres buffered atualmente de um fluxo
fopen, freopen ou fdopen
Abrir um fluxo
fread ou fwrite
Executar entrada binária
fseek, rewind, ftell, fgetpos ou fsetpos
Reposicionar o ponteiro de arquivo de um fluxo
getc, fgetc, getchar ou getw
Obter um caractere ou palavra a partir de um fluxo de entrada
gets ou fgets
Obter uma string de um fluxo
getwc, fgetwc ou getwchar
Obter um caractere amplo a partir de um fluxo de entrada
getws ou fgetws
Obter uma string de um fluxo
printf, fprintf, sprintf, wsprintf, vprintf, vfprintf, vsprintf, ou vwsprintf
Imprimir saída formatada
putc, putchar, fputc ou putw
Escreva um caractere ou uma palavra para um fluxo
coloca ou fputs
Escreva uma string para um fluxo
putwc, putwchar ou fputwc
Escreva um caractere ou uma palavra para um fluxo
putws ou fputws
Escreva uma cadeia de caracteres larga para um fluxo
scanf, fscanf, sscanf ou wsscanf
Converter entrada formatada
setbuf, setvbuf, setbuffer ou setlinebuf
Atribuir buffering a um fluxo
ungetc ou ungetwc
Empurre um caractere de volta para o fluxo de entrada

Interfaces de E/S Terminal

As interfaces de E/S de terminal operam entre um processo e o kernel, fornecendo funções como buffering e saída formatada. Todo terminal e pseudo-terminal tem uma estrutura mesinha que contém o ID do grupo de processos atuais. Este campo identifica o grupo de processos para receber os sinais associados ao terminal. As interfaces de E/S de terminal podem ser acessadas através do comando iostat , que monitora o carregamento do dispositivo do sistema de E/S, e o daemon uprintfd , que permite que as mensagens do kernel sejam gravadas no console do sistema.

As características do terminal podem ser ativadas ou desativadas através das seguintes sub-rotinas:

cfgetospeed, cfsetospeed, cfgetispeed, ou cfsetispeed
Obter e configurar taxas de baud de entrada e saída
ioctl
Executa funções de controle associadas ao terminal
termdef
Características do terminal de consultas
tcdreno
Aguarda saída para conclusão
tcflow
Executa funções de controle de fluxo
tcflush
Descarta dados da fila especificada
tcgetpgrp
Obtém ID do grupo de processos de primeiro plano
tcsendbreak
Envia uma quebra em uma linha de dados de série assíncrona
tcsetattr
Estado terminal de conjuntos
ttylock, ttywait, ttyunlock, ou ttylocked
Funções de bloqueio de tty controle
ttyname ou isatty
Obter o nome de um terminal
ttyslot
Encontra o slot no arquivo utmp para o usuário atual

Interfaces de E/S Asynchronous

As subroutines de E/S assíncronas permitem que um processo inicie uma operação de E/S e tenha o retorno de subroutine imediatamente após a operação ser iniciada ou enfileirada. Outra subroutine é obrigada a esperar que a operação seja concluída (ou retorne imediatamente se a operação já estiver concluída). Isso significa que um processo pode sobrepor sua execução com a sua E/S de E/S ou sobreposição entre diferentes dispositivos. Embora a E/S assíncrona não melhore significativamente o desempenho para um processo que esteja lendo a partir de um arquivo de disco e escrevendo para outro arquivo de disco, a E/S assíncrona pode proporcionar melhorias significativas de desempenho para outros tipos de programas orientados a E/S, como programas que despedireem um disco a uma fita magnética ou exibem uma imagem em um display de imagem.

Apesar de não ser necessário, um processo que está executando E/S assíncrona pode dizer ao kernel para notificá-lo quando um descritor especificado estiver pronto para E/S (também chamado de E/S orientada por sinal). Ao utilizar o LEGACY AIO, o kernel notifica o processo do usuário com o sinal SIGIO. Ao utilizar o POSIX AIO, a estrutura sigevent é usada pelo programador para determinar qual sinal para o kernel utilizar para notificar o processo do usuário. Os sinais incluem SIGIO, SIGUSR1e SIGUSR2.

Para usar E/S assíncrona, um processo deve executar as seguintes etapas:

  1. Estabeleça um manipulador para o sinal SIGIO . Esta etapa é necessária apenas se a notificação pelo sinal for solicitada.
  2. Configure o ID do processo ou o ID do grupo de processos para receber os sinais SIGIO . Esta etapa é necessária apenas se a notificação pelo sinal for solicitada.
  3. Ativar E/S assíncrona. O administrador do sistema geralmente determina se a E/S assíncrona é carregada (ativada). A ativação ocorre na inicialização do sistema.

As seguintes subroutines de E/S assíncronas são fornecidas:

aio_cancelar
Cancela uma ou mais solicitações de E/S assíncronas pendentes
aio_error
Recupera o status de erro de uma solicitação de E/S assíncrona
aio_fsync
Sincroniza arquivos assíncronos.
aio_nwait
Suspende o processo de chamada até que um determinado número de solicitações de E/S assíncronas sejam concluídos.
aio_read
Lê assíncrona a partir de um descritor de arquivo
aio_return
Recupera o status de retorno de uma solicitação de E/S assíncrona
aio_suspender
Suspende o processo de chamada até que uma ou mais solicitações de E/S assíncronas sejam concluídas
aio_write
Escreve de forma assíncrona a um descritor de arquivo
lio_listio
Inicia uma lista de solicitações de E/S assíncronas com uma única chamada
poll ou select
Verificar status de E/S de vários descritores de arquivos e filas de mensagens

Para uso com a subroutine poll , os seguintes arquivos de cabeçalho são fornecidos:

poll.h
Define as estruturas e as bandeiras usadas pela subroutine poll
aio.h
Define a estrutura e as bandeiras usadas pelos subroutines aio_read, aio_writee aio_suspensão