O que acontece quando eu fecho () um descritor de arquivo?

16

Estou tentando obter a imagem completa com descritores de arquivos. Digamos que eu tenha o process1 que inicialmente possui esses descritores de arquivo:

 _process1_
|          |
| 0 stdin  |
| 1 stdout |
| 2 stderr |
|__________|

Depois fecho o descritor de arquivo 1:

close(1);

O descritor de arquivo 1 traduz (pontos) para a stdout FILE structure na Open Files Table do kernel.

Com o código acima, o descritor de arquivo 1 é excluído da tabela do processo, que se torna:

 _process1_
|          |
| 0 stdin  |
| 2 stderr |
|__________|

Mas o que acontece no kernel? A estrutura stdout FILE é desalocada? Como isso é possível se stdout é um arquivo especial (o monitor) e provavelmente está sendo usado por outros processos? E quanto às estruturas FILE que são apenas arquivos normais (.txt por exemplo)? E se tal arquivo estiver sendo usado por outro processo?

    
por Pithikos 28.11.2011 / 03:30

2 respostas

13

The file descriptor 1 translates to the stdout FILE structure in the Kernel's Open Files Table.

Isso é um mal-entendido. A tabela de arquivos do kernel não tem nada a ver com estruturas de arquivos do espaço do usuário.

Em qualquer caso, o kernel tem dois níveis de indireção. Existe a estrutura interna que representa o arquivo em si, que é uma referência contada. Há uma "descrição de arquivo aberto" que é contada de referência. E depois há o identificador de arquivo, que não é contado de referência. A estrutura do arquivo aponta o caminho para o próprio inode. A descrição do arquivo aberto contém coisas como o modo de abertura e o ponteiro de arquivo.

Quando você liga para fechar, você sempre fecha o identificador de arquivo. Quando um identificador de arquivo é fechado, a contagem de referência em sua descrição de arquivo aberto é diminuída. Se for zero, a descrição do arquivo aberto também será liberada e a contagem de referência no próprio arquivo será diminuída. Somente se isso for zero, a estrutura de arquivos do kernel será liberada.

Não há chance de um processo liberar um recurso que outro processo está usando porque os recursos compartilhados são contados por referência.

    
por 28.11.2011 / 07:29
6

Neste caso, não muito acontecerá. stdin, stdout e stderr todos tendem a ser clones do mesmo descritor de arquivo. O contador de referência para o descritor de arquivo será decrementado por um. O mesmo descritor de arquivo é normalmente mantido pelo shell a partir do qual o programa foi executado, portanto, o descritor de arquivo precisa ser mantido.

O kernel mantém contagens de referência para todos os arquivos (inodes) que estão abertos. Contanto que a contagem de referência seja maior que zero, o arquivo será mantido. Eu esperaria um contador separado é mantido para identificadores de arquivo aberto. Quando isso atinge zero, o kernel pode liberar a memória usada pelo manipulador de arquivos.

Quando todas as referências ao arquivo (entradas de diretório e identificadores de arquivo) tiverem sido removidas, o código do sistema de arquivos marcará o inode para reutilização. Quaisquer blocos que o arquivo tenha são disponibilizados para alocação. Muitos sistemas de arquivos apagam os ponteiros de bloco no inode quando ele é liberado. Isso dificulta a recuperação de um arquivo excluído. As atualizações no disco podem ser armazenadas em buffer e concluídas posteriormente.

    
por 28.11.2011 / 04:36