Por que existe open()
e close()
existe no design do sistema de arquivos Unix?
O sistema operacional não pôde apenas detectar a primeira vez read()
ou write()
foi chamado e fazer o open()
que normalmente faria?
files
filesystems
architecture
api
user5977637
fonte
fonte
open()
existe. "O sistema operacional não conseguiu detectar a primeira vez que lê () ou escreve () e faz o que abrir () normalmente faria?" Existe uma sugestão correspondente para quando o fechamento aconteceria?read()
ouwrite()
qual arquivo acessar? Presumivelmente, passando o caminho. E se o caminho do arquivo mudar enquanto você o acessa (entre duasread()
ouwrite()
chamadas)?read()
ewrite()
, apenasopen()
.Respostas:
Dennis Ritchie menciona em «A evolução do sistema de tempo compartilhado Unix» que
open
eclose
junto comread
,write
ecreat
estavam presentes no direito sistema desde o início.Eu acho que um sistema sem
open
eclose
não seria inconcebível, no entanto, acredito que isso complicaria o design. Você geralmente deseja fazer várias chamadas de leitura e gravação, não apenas uma, e isso provavelmente ocorreu especialmente nos computadores antigos com RAM muito limitada na qual o UNIX se originou. Ter um identificador que mantém sua posição atual do arquivo simplifica isso. Seread
ouwrite
devolverem a alça, teriam que retornar um par - uma alça e seu próprio status de retorno. A parte do identificador do par seria inútil para todas as outras chamadas, o que tornaria esse arranjo estranho. Deixar o estado do cursor para o kernel permite melhorar a eficiência, não apenas através de buffer. Há também algum custo associado à pesquisa de caminho - ter um identificador permite que você pague apenas uma vez. Além disso, alguns arquivos na visão de mundo UNIX nem têm um caminho de sistema de arquivos (ou não - agora eles têm coisas do tipo/proc/self/fd
).fonte
open
/close
, certamente implementaria coisas como/dev/stdout
permitir a tubulação.open()
paraget_inode()
e fez todo o sistema mais rígido (impossível de ler / escrever o mesmo arquivo em várias posições ao mesmo tempo).Todas as chamadas
read
ewrite
teriam que passar essas informações em cada operação:Se você considerar os independentes chamadas
open
,read
,write
eclose
para ser mais simples do que a de finalidade única E / S mensagem é baseada em sua filosofia de design. Os desenvolvedores do Unix escolheram usar operações e programas simples que podem ser combinados de várias maneiras, em vez de uma única operação (ou programa) que faz tudo.fonte
read
ewrite
não estão restritos a arquivos que vivem em um sistema de arquivos, e essa é uma decisão fundamental de design no Unix, como explica o pjc50.lseek
)O conceito de manipulação de arquivo é importante devido à escolha de design do UNIX de que "tudo é um arquivo", incluindo itens que não fazem parte do sistema de arquivos. Como unidades de fita, teclado e tela (ou teletipo!), Leitores de cartão / fita perfurados, conexões seriais, conexões de rede e (a principal invenção do UNIX) conexões diretas a outros programas chamados "pipes".
Se você olhar para muitos dos utilitários UNIX padrão simples
grep
, como , especialmente em suas versões originais, perceberá que eles não incluem chamadas paraopen()
eclose()
apenasread
ewrite
. Os identificadores de arquivo são configurados fora do programa pelo shell e transmitidos quando são iniciados. Portanto, o programa não precisa se importar se está gravando em um arquivo ou em outro programa.Bem como
open
, as outras formas de obtenção de descritores de arquivos sãosocket
,listen
,pipe
,dup
, e um muito mecanismo de Heath Robinson para o envio de descritores de arquivo através de tubos: https://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux -socketEditar: algumas notas de aula descrevendo as camadas de indireção e como isso permite que o O_APPEND funcione de maneira sensata. Observe que manter os dados do inode na memória garante que o sistema não precise ir buscá-los novamente para a próxima operação de gravação.
fonte
creat
, elisten
não cria um fd, mas quando (e se) uma solicitação é recebida durante a escutaaccept
cria e retorna um fd para o novo soquete (conectado).pipe
foi introduzido alguns anos após o início do desenvolvimento no Unix.A resposta é não, porque abrir () e fechar () criam e destroem um identificador, respectivamente. Há momentos (bem, o tempo todo, realmente) em que você pode querer garantir que você é o único chamador com um nível de acesso específico, pois outro chamador (por exemplo) gravando em um arquivo que você está analisando inesperadamente pode deixar uma aplicação em um estado desconhecido ou levar a um bloqueio ou impasse, por exemplo, o lema de Dining Philosophers.
Mesmo sem essa consideração, há implicações de desempenho a serem consideradas; close () permite ao sistema de arquivos (se for apropriado ou se você solicitou) liberar o buffer que você estava ocupando, uma operação cara. Várias edições consecutivas em um fluxo na memória são muito mais eficientes do que vários ciclos de leitura / gravação / modificação essencialmente não relacionados em um sistema de arquivos que, pelo que você sabe, existe a meio mundo de distância, espalhado por um datacenter com armazenamento em massa de alta latência. Mesmo com o armazenamento local, a memória é tipicamente muitas ordens de magnitude mais rápida que o armazenamento em massa.
fonte
Open () oferece uma maneira de bloquear arquivos enquanto eles estão em uso. Se os arquivos fossem abertos automaticamente, lidos / gravados e depois fechados novamente pelo sistema operacional, não haveria nada para impedir que outros aplicativos alterassem esses arquivos entre as operações.
Embora isso possa ser gerenciado (muitos sistemas suportam acesso não exclusivo a arquivos) para simplificar, a maioria dos aplicativos supõe que os arquivos abertos não sejam alterados.
fonte
Como o caminho do arquivo pode se mover enquanto você assume que permanecerá o mesmo.
fonte
A leitura e gravação em um sistema de arquivos pode envolver uma grande variedade de esquemas de buffer, manutenção do SO, gerenciamento de disco de baixo nível e uma série de outras ações em potencial. Portanto, as ações
open()
eclose()
servem como configuração para esses tipos de atividades ocultas. Diferentes implementações de um sistema de arquivos podem ser altamente personalizadas conforme necessário e ainda permanecem transparentes para o programa de chamada.Se o sistema operacional não tivesse aberto / fechado, com
read
ouwrite
, essas ações de arquivo ainda precisariam executar qualquer inicialização, liberação / gerenciamento de buffer, etc, sempre. Isso exige muita sobrecarga para leituras e gravações repetitivas.fonte
O mantra do Unix é "oferecer uma maneira de fazer as coisas", o que significa "fatorar" em partes (reutilizáveis) para serem combinadas à vontade. Ou seja, nesse caso, separe a criação e a destruição de identificadores de arquivo do seu uso. Benefícios importantes vieram mais tarde, com pipes e conexões de rede (eles também são manipulados por meio de identificadores de arquivo, mas são criados de outras maneiras). Ser capaz de enviar identificadores de arquivos (por exemplo, passá-los para processos filhos como "arquivos abertos" que sobrevivem a um processo
exec(2)
e até a processos não relacionados através de um canal) só é possível dessa maneira. Especialmente se você quiser oferecer acesso controlado a um arquivo protegido. Então você pode, por exemplo, abrir/etc/passwd
para escrever e passar isso para um processo filho que não pode abrir esse arquivo para escrever (sim, eu sei que esse é um exemplo ridículo, fique à vontade para editar com algo mais realista).fonte