Próbuję uzyskać cały obraz z deskryptorami plików. Powiedzmy, że mam proces1, który początkowo ma następujące deskryptory plików:
_process1_
| |
| 0 stdin |
| 1 stdout |
| 2 stderr |
|__________|
Następnie zamykam deskryptor pliku 1:
close(1);
Deskryptor pliku 1 tłumaczy (wskazuje) na standardową strukturę PLIK w tabeli otwartych plików jądra .
Z powyższym kodem deskryptor pliku 1 zostaje usunięty z tabeli procesu, który staje się:
_process1_
| |
| 0 stdin |
| 2 stderr |
|__________|
Ale co dzieje się w jądrze? Czy stdout
struktura PLIKU zostaje zwolniona? Jak to możliwe, jeśli stdout jest specjalnym plikiem (monitorem) i prawdopodobnie jest wykorzystywany przez inne procesy? Co ze strukturami PLIKÓW, które są zwykłymi plikami (na przykład .txt)? Co jeśli taki plik jest używany przez inny proces?
źródło
open
powiedzie.W takim przypadku niewiele się wydarzy. stdin, stdout i stderr są zwykle klonami tego samego deskryptora pliku. Licznik referencyjny deskryptora pliku zostanie zmniejszony o jeden. Ten sam deskryptor pliku zwykle znajduje się w powłoce, z której uruchomiono program, więc deskryptor pliku musi być przechowywany.
Jądro przechowuje liczniki referencji dla wszystkich otwartych plików (i-węzłów). Dopóki liczba referencji jest większa od zera, plik będzie przechowywany. Spodziewałbym się, że dla otwartych uchwytów plików jest przechowywany osobny licznik. Gdy osiągnie zero, jądro może zwolnić pamięć używaną przez uchwyt pliku.
Po usunięciu wszystkich odniesień do pliku (pozycji katalogu i uchwytów plików) kod systemu plików oznaczy i-węzeł do ponownego użycia. Wszelkie bloki pliku są udostępniane do alokacji. Wiele systemów plików wyczyści wskaźniki blokowe w i-węzle, gdy zostanie zwolnione. Utrudnia to odzyskanie usuniętego pliku. Aktualizacje dysku mogą być buforowane i ukończone w późniejszym czasie.
źródło
cat > some.file
, kot dostaje EOF na standardowe wejście, ale skorupa nie. (2) Dlaczego liczenie referencji? Dlaczego nie jakaś forma śmieci? Czy GC nie jest dużo lepsze w przestrzeni użytkownika?cat > some.file
to, co faktycznie robi, to rozwidla się, otwierając plik „some.file” i przypisując go do deskryptora pliku 1, a następnie robi toexec("cat")
. Kiedy proces jest wykonywany (d), dziedziczy deskryptory otwartych plików.