Bir dosya tanımlayıcısını kapattığımda () ne olur?


16

Dosya tanıtıcıları ile tüm resmi almaya çalışıyorum. Başlangıçta bu dosya tanımlayıcıları olan process1 var diyelim:

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

Sonra dosya tanımlayıcı 1'i kapatıyorum:

close(1);

Dosya tanımlayıcı 1 stdout FILE yapısına (nokta) çevirir , çekirdeğin Açık Dosyalar Tablosundaki .

Yukarıdaki kodla birlikte dosya tanımlayıcı 1, işlem tablosundan şu şekilde silinir:

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

Ama çekirdekte ne olur? Does stdoutDOSYA yapısı ayırmanın olsun? Stdout özel bir dosya (monitör) ise ve muhtemelen diğer işlemler tarafından kullanılıyorsa bu nasıl mümkün olabilir? Sadece normal dosyalar (örneğin .txt) olan DOSYA yapıları ne olacak? Böyle bir dosya başka bir işlem tarafından kullanılıyorsa ne olur?

Yanıtlar:


13

Dosya tanımlayıcı 1, Çekirdek Açık Dosyalar Tablosundaki stdout FILE yapısına çevirir.

Bu bir yanlış anlama. Çekirdeğin dosya tablosunun kullanıcı alanı dosya yapılarıyla hiçbir ilgisi yoktur.

Her durumda, çekirdeğin iki dolaylı dolaylı seviyesi vardır. Sayılan başvurunun kendisi olan dosyanın kendisini temsil eden iç yapı vardır. Başvurulan "açık dosya açıklaması" var. Ve sonra başvurulan dosya tanıtıcısı var. Dosya yapısı inodeun kendisine giden yolu gösterir. Açık dosya açıklaması, açık mod ve dosya işaretçisi gibi şeyler içerir.

Close aradığınızda, her zaman dosya tanıtıcısını kapatırsınız. Bir dosya tanıtıcısı kapatıldığında, açık dosya açıklamasındaki başvuru sayısı azaltılır. Sıfıra giderse, açık dosya açıklaması da serbest bırakılır ve dosyanın kendisindeki referans sayısı azaltılır. Yalnızca bu sıfıra giderse, çekirdeğin dosya yapısı serbest kalır.

Paylaşılan kaynaklar referans sayıldığından, bir işlemin başka bir işlemin kullandığı bir kaynağı serbest bırakma şansı yoktur.


Cevabınızdaki terminolojiyi anlamakta biraz güçlük çekiyorum. Sanırım dosya tanıtıcısı "dosya ofseti" anlamına geliyor. Demek istediğin bu muydu? Ayrıca dosya tanıtıcısı ile ne demek istiyorsun ?
Geek

Bu doğru, "dosya ofseti" ile, sonraki okuma veya yazma işleminin gerçekleşeceği ofseti kastediyorum. Bir "dosya tanıtıcısı", bir işlem ile açık bir dosya açıklaması arasındaki bağlantıdır; openbaşarılı olduğunuzda geri alırsınız .
David Schwartz

6

Bu durumda çok fazla şey olmayacak. stdin, stdout ve stderr'in tümü aynı dosya tanımlayıcısının klonları olma eğilimindedir. Dosya tanımlayıcı için referans sayacı bir azaltılır. Aynı dosya tanımlayıcı genellikle programın çalıştırıldığı kabuk tarafından tutulur, bu nedenle dosya tanımlayıcısının tutulması gerekir.

Çekirdek, açık olan tüm dosyalar (düğümler) için referans sayılarını tutar. Referans sayısı sıfırdan büyük olduğu sürece dosya tutulur. Açık dosya tanıtıcıları için ayrı bir sayaç tutulması beklenir. Bu sıfıra ulaştığında, çekirdek dosya tanıtıcısı tarafından kullanılan belleği serbest bırakabilir.

Dosyaya yapılan tüm başvurular (dizin girişleri ve dosya tanıtıcıları) kaldırıldığında, dosya sistemi kodu inode'u yeniden kullanılmak üzere işaretler. Dosyanın sahip olduğu tüm bloklar ayrılmaya hazır hale getirilir. Birçok dosya sistemi, serbest bırakıldığında inode içindeki blok işaretçileri temizler. Bu, silinen bir dosyayı kurtarmayı zorlaştırır. Diske yapılan güncellemeler daha sonra arabelleğe alınabilir ve tamamlanabilir.


1
İki soru: (1) Dosya tanımlayıcıları gerçekten ref sayılıyor mu? A'yı kontrol ettiğinizde cat > some.file, kedi stdin üzerinde bir EOF alır, ancak kabuk almaz. (2) Neden referans sayımı? Neden bir çeşit çöp toplama değil? GC kullanıcı alanında çok daha iyi değil mi?
Bruce Ediger

BillThor'un cevabına genişleme: Normal durumlarda stdin, stdout ve stderr, TTY cihazına açık dosya tanıtıcılarıdır. Dosya tutamacını kapatırsanız, bu TTY cihazı hala oradadır ve daha sonra tekrar açılabilir.
Patrick

1
@BruceEdiger: (1) kabuk cat > some.filegerçekten yaptığı şeyi çalıştırdığında , 'some.file' dosyasını açar ve dosya tanımlayıcı 1'e atarsa, o zaman yapar exec("cat"). Bir işlem exec () 'd olduğunda, açık dosya tanımlayıcılarını devralır.
Patrick

@BruceEdiger (2) Referans sayımı, aynı türdeki diğer veri yapılarına işaretçi (veya biten işaretçi zincirleri) içermeyen veri yapılarında kullanıldığında mükemmel bir şekilde çöp toplama biçimidir. Ayrıca, çekirdek alanında da oluyor (çok önemli değil).
Gilles 'SO- kötü olmayı kes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.