Yürütülen Dosyaların Kilitlenmesi: Windows yapar, Linux kilitler. Neden?


83

Bir dosyanın Windows (.exe veya .dll) üzerinde yürütüldüğünü, kilitlendiğini ve silinemeyeceğini, taşınamayacağını veya değiştirilemeyeceğini fark ettim.

Linux, diğer taraftan, dosya yürütme kilidi yok ve siz yapabilirsiniz silmek, taşımak ve onları değiştirebilir.

Linux kilitlemediği halde Windows neden kilitleniyor? Kilitlemenin bir avantajı var mı?


7
Gezginde , belirli bir dosyayı kilitleyen işlemleri görüntüleyebilen içerik menüsüne bir menü girişi ekleyen WhoLockMe adlı bir yardımcı program vardır . Garip dosya kilitleme hataları aldığınızda son derece kullanışlıdır. Düzenleme: Bunun soruyu yanıtlamadığını biliyorum, ancak bağlamda ayrı bir yanıtı garanti edecek kadar yararlı olduğunu düşündüm (sadece bir yorumun aksine).
JesperE

Yanıtlar:


106

Linux'un bir referans-sayma mekanizması vardır, bu nedenle dosyayı yürütülürken silebilirsiniz ve bazı işlemlerin (daha önce açmış olan) onun için açık bir tanıtıcısı olduğu sürece var olmaya devam edecektir. Dosyayı sildiğinizde, dosyanın dizin girişi kaldırılır, bu nedenle daha fazla açılamaz, ancak bu dosyayı zaten kullanan işlemler yine de onu kullanabilir. Bu dosyayı kullanan tüm işlemler sona erdiğinde, dosya otomatik olarak silinir.

Windows bu özelliğe sahip değildir, bu nedenle, dosyadan yürütülen tüm işlemler bitene kadar dosyayı kilitlemeye zorlanır.

Linux davranışının tercih edilebilir olduğuna inanıyorum. Muhtemelen bazı derin mimari nedenler vardır, ancak en çekici bulmamın ana (ve basit) nedeni, Windows'ta bazen bir dosyayı silememeniz, nedenini bilmiyorsunuz ve tek bildiğiniz, bazı işlemlerin onu içeride tuttuğudur. kullanın. Linux'ta asla olmaz.


2
Hangi işlemin dosya / klasör kullandığını görmek için Windows'ta Process Explorer gibi bir araç kullanabileceğinizi unutmayın.
J c

15
Linux davranışı lehine pratik bir neden, işletim sistemini ve sistemdeki diğer yazılımları çalışırken güncelleyebilmeniz ve asla / nadiren yeniden başlatabilmenizdir (çalışan çekirdeği yeniden başlatmadan bile değiştirebilirsiniz, sadece çağrılması yeterince zordur. çalışma süresi açısından kritik uygulamalar için).
joelhardi

7
"Windows bu özelliğe sahip değil" ... emin misin? NT çekirdeği, nesneleri tutamaçlar ve referanslarla yeniden saymaya dayanır.
Adam Mitz

11
Windows aslında başka bir işlemin açıkken bir dosyaya ne yapabileceğini tanımlayabileceğiniz 3 bit içerir. FILE_SHARE_DELETEBit ayarlanmışsa , dosya açıkken silinebilir . PE yükleyicinin (EXE'leri ve DLL'leri yükleyen) bu biti ayarladığını sanmıyorum. Tutamaçlar referans olarak sayılır ve bir silme işleminde son tutamaç bırakıldığında dosya kaybolur, ancak bununla Unix arasındaki fark, NT'nin bu olduğunda aynı isimle yeni bir dosyanın oluşturulmasını engellemesidir.
asveikau

2
Comonad'ın söylediği şey tamamen yanlıştır, NTFS elbette Hardlink'leri kullanır ve her zaman kullandı, sembolik bağlantılar Windows Vista'ya eklenmiştir. Windows'un ref copunting kullanmaması tamamen yanlıştır, sadece CreateFile gibi API'leri okur ve hangi durumlarda dosyaların silinebileceğini vb. Açıkça belirtir. Ve sorunun gerçek yanıtı için de uygun yer burasıdır: CreateFile, açık dosyaların zorunlu olarak kilitlenmesini kontrol eden ve uygulamaların karar vermesine izin veren dwShareMode olarak sınıflandırılmış bir argümana sahiptir. Varsayılan değer özel bir kilittir ...
Thorsten Schöning

30

Gibi bildiğim kadarıyla, linux yapar yayınlandığı zaman kilit yürütülebilir - ancak, kilitler inode'ları . Bu, "dosyayı" silebileceğiniz anlamına gelir, ancak inode hala dosya sisteminde, dokunulmamış ve gerçekten sildiğiniz tek şey bir bağlantıdır.

Unix programları, dosya sistemi hakkında her zaman bu şekilde düşünür, geçici bir dosya oluşturur, açar, adını siler. Dosyanız hala var, ancak ad başkalarının kullanması için serbest bırakıldı ve başka kimse göremiyor.


"her zaman"? Herhangi bir örnek?
Mez

4
Google'a "unix güvenli geçici dosya" hakkında sorular sorun ve tekniğin iyi bilindiğini ve yaygın olarak kullanıldığını gösterecek kadar yeterli açıklama bulacaksınız. Verecek belirli örneklerim olmasa da, geçici dosyaları kullanan güvenlik bilincine sahip herhangi bir uygulamanın bunu yaptığını söyleyebilirim.
Dave Sherohman

26

Linux dosyaları kilitliyor. Yürütülmekte olan bir dosyanın üzerine yazmaya çalışırsanız, "ETXTBUSY" (Metin dosyası meşgul) mesajı alacaksınız. Ancak dosyayı kaldırabilirsiniz ve çekirdek, dosyaya son referans kaldırıldığında dosyayı siler. (Makine temiz bir şekilde kapatılmadıysa, bu dosyalar dosya sistemi kontrol edildiğinde "Silinen düğümde sıfır d-zamanı vardı" mesajlarının nedenidir, tam olarak silinmemişlerdir, çünkü çalışan bir işlemin bir referansı vardır, ve şimdi öyleler.)

Bunun bazı önemli avantajları vardır, çalıştırılabilir dosyayı silerek, değiştirerek ve ardından işlemi yeniden başlatarak çalışan bir işlemi yükseltebilirsiniz. Hatta init bile bu şekilde yükseltilebilir, çalıştırılabilir dosyayı değiştirebilir ve ona bir sinyal gönderebilir ve yeniden başlatma gerektirmeden kendisini yeniden çalıştırır (). (Bu normalde, yükseltmesinin bir parçası olarak paket yönetim sisteminiz tarafından otomatik olarak yapılır)

Windows altında, kullanımda olan bir dosyayı değiştirmek, genellikle hiçbir işlemin çalışmadığından emin olmak için yeniden başlatma gerektiren büyük bir güçlük gibi görünür.

Çok büyük bir günlük dosyanız varsa ve onu kaldırmanız gibi bazı sorunlar olabilir, ancak dosyayı yeniden açmak için o dosyaya giriş yapan işlemi söylemeyi unutmayın, referansı tutacaktır ve merak edeceksiniz. diskiniz neden birden fazla boş alan almadı.

Bu numarayı Linux altında geçici dosyalar için de kullanabilirsiniz. dosyayı açın, silin ve ardından dosyayı kullanmaya devam edin. İşleminiz sona erdiğinde (ne sebeple olursa olsun - elektrik kesintisi bile olsa), dosya silinecektir.

Lsof ve fuser gibi programlar (veya sadece / proc // fd'de gezinerek) size hangi işlemlerin artık bir adı olmayan dosyaların açık olduğunu gösterebilir.


6

Bence linux / unix aynı kilitleme mekanizmasını kullanmıyor çünkü bunlar çok kullanıcılı bir sistem olarak sıfırdan inşa edildi - bu da birden fazla kullanıcının aynı dosyayı, hatta belki de farklı amaçlar için kullanma olasılığını bekleyebilir.

Kilitlemenin bir avantajı var mı? Eh, işletim sisteminin yönetmesi gereken işaretlerin miktarını muhtemelen azaltabilir, ancak günümüzde tasarruf miktarı oldukça önemsizdir. Kilitlemenin düşünebildiğim en büyük avantajı şudur: kullanıcı tarafından görülebilen bazı belirsizliklerden tasarruf edersiniz. Eğer a kullanıcısı bir ikili dosya çalıştırıyorsa ve kullanıcı b onu silerse, o zaman gerçek dosyanın A kullanıcısının işlemi tamamlanana kadar orada kalması gerekir. Yine de, B Kullanıcısı veya başka herhangi bir kullanıcı dosya sistemine bakarsa, onu bulamazlar - ancak yer kaplamaya devam eder. Benim için gerçekten büyük bir endişe değil.

Bence bu daha çok pencerenin dosya sistemleriyle geriye dönük uyumlulukla ilgili bir soru.


Bu bağlamda "Windows", Windows NT satırıdır. Bu, tek kullanıcılı Windows 3.11'in çok kullanıcılı halefi olarak tasarlanmıştır. Multics'in tek kullanıcılı halefi olan Unix ile karşılaştırın.
MSalters

6

Windows konusunda çok mutlak olduğunuzu düşünüyorum. Normalde, bir yürütülebilir dosyanın kod kısmı için takas alanı ayırmaz. Bunun yerine, excutable & DLL'lerde bir kilit tutar. Atılan kod sayfalarına tekrar ihtiyaç duyulursa, bunlar basitçe yeniden yüklenir. Ancak / SWAPRUN ile bu sayfalar takas halinde tutulur. Bu, CD veya ağ sürücülerindeki yürütülebilir dosyalar için kullanılır. Bu nedenle, pencerelerin bu dosyaları kilitlemesi gerekmez.

.NET için Shadow Copy'ye bakın .


1

Bir dosyada çalıştırılan kodun kilitlenmesi gerekip gerekmediği bir tasarım kararı ise ve MS pratikte açık avantajları olduğu için kilitlemeye karar vermişse: Bu şekilde hangi kodun hangi sürümde hangi uygulama tarafından kullanıldığını bilmenize gerek kalmaz. Bu, çoğu insan tarafından basitçe göz ardı edilen Linux varsayılan davranışıyla ilgili büyük bir sorundur. Sistem çapında kütüphaneler değiştirilirse, hangi uygulamaların bu tür kütüphanelerin kodunu kullandığını kolayca bilemezsiniz, çoğu zaman elde edebileceğiniz en iyi şey, paket yöneticisinin bu kütüphanelerin bazı kullanıcılarını tanıyıp yeniden başlatmasıdır. Ancak bu yalnızca genel olarak işe yarar ve Postgres ve libs gibi şeyleri iyi bilir. Daha ilginç senaryolar, bazı üçüncü taraf kitaplara karşı kendi uygulamanızı geliştirmeniz ve bunların değiştirilmesidir, çünkü çoğu zaman paket yöneticisi uygulamanızı bilmiyordur. Ve şu' Sadece yerel C kodu veya benzeri bir sorun değil, hemen hemen her şeyde olabilir: Sadece httpd'yi mod_perl ile kullanın ve bir paket yöneticisi kullanarak yüklenen bazı Perl kitaplıkları ve paket yöneticisinin herhangi bir nedenle bu Perl kitaplıklarını güncellemesine izin verin. Bağımlılıkları bilmediği için httpd'nizi yeniden başlatmaz. Bunun gibi pek çok örnek var, çünkü herhangi bir dosya herhangi bir çalışma zamanı tarafından bellekte kullanımda olan kod içerebilir, Java, Python ve benzeri şeyleri düşünün.

Bu nedenle, dosyaları varsayılan olarak kilitlemenin iyi bir seçim olabileceği fikrine sahip olmak için iyi bir neden var. Yine de bu nedenlere katılmanıza gerek yok.

Peki MS ne yaptı? Basitçe, çağıran uygulamaya dosyaların kilitlenip kilitlenmeyeceğine karar verme şansı veren bir API oluşturdular, ancak bu API'nin varsayılan değerinin ilk çağıran uygulamaya özel bir kilit sağlamak olduğuna karar verdiler. CreateFile ve dwShareModeargümanının etrafındaki API'ye bir göz atın . Bazı uygulamalar tarafından kullanılan dosyaları silememenizin nedeni budur, kullanım durumunuzu umursamaz, varsayılan değerleri kullanır ve bu nedenle Windows tarafından bir dosya için özel bir kilit alır.

Lütfen insanların size Windows hakkında HANDLE'larda ref saymayı kullanmadığını veya Sabit Bağlantıları desteklemediğini söyleyenlere inanmayın, bu tamamen yanlış. HANDLEs kullanan hemen hemen her API, ref sayma ile ilgili davranışını belgeler ve NTFS ile ilgili hemen hemen tüm makalelerde, belgede Hardlink'leri desteklediğini ve her zaman desteklediğini kolayca okuyabilirsiniz. Windows Vista'dan beri Symlinks desteği vardır ve Hardlinks Desteği, belirli bir dosya vb. İçin hepsini okumak için API'ler sağlayarak iyileştirilmiştir .

Ayrıca, sadece örneğin bir dosyayı tanımlamak için kullanılan yapıların bir göz atmak istersin ext4 kıyaslandığında NTFS ortak noktamız var ki. Her ikisi de verileri dosya adı gibi özniteliklerden ayıran kapsam kavramıyla çalışır ve inode'lar daha eski, ancak buna benzer bir kavram için hemen hemen başka bir addır. Wikipedia bile makalesinde her iki dosya sistemini de listeliyor .

Ağdaki diğer işletim sistemlerine kıyasla Windows'ta dosya kilitlemede gerçekten çok fazla FUD var, tıpkı birleştirme gibi. Bu FUD'nin bir kısmı Wikipedia'da biraz okunarak çıkarılabilir .


Paylaşılan bağımlılıkların sürüm yönetimi hakkındaki saçmalıklar konu dışıdır. Güncellemeleri yeniden başlatma gerektirse bile bu sorunları halletmelisiniz. Windows'ta bir adı bile vardır: DLL cehennemi. Ayrıca, tanımladığınız çalışma zamanı davranışları, dosyanın zaten belleğe yüklenmiş olduğu ve kullanılabilir durumda kaldığı Linux durumu tarafından tamamen ele alınır; Windows, dosyanın kilidini açmak için yeniden başlatmaya zorladığında olduğu gibi, uygulama yeniden başlayana kadar eski sürümle çalışmaya devam edecektir. Bu cephede hiçbir avantaj yok.
jpmc26

DLL cehennemi elbette konuyu tamamen kaçırıyor ve artık 90'lara sahip değiliz, sadece bu gibi şeyleri okuyun WinSxS. Ek olarak, önemli olan şeyleri belleğe yüklemek ve orada tutmakla ilgili değildir, Windows gerektiğinde tam olarak bunu yapar, dosyaların değiştirilip değiştirilmeyeceğini bilmek ve karar vermek ve buna karar vermekten kimin sorumlu olduğunu bilmekle ilgilidir. Windows-API, dosyanın ilk kullanıcısının karar vermesini sağlar ve bu çok mantıklıdır.
Thorsten Schöning

Ama benim amacım bu: bir DLL'nin hangi sürümünün kullanılacağına karar vermek DLL cehenneminin bir parçasıdır. Windows'un bazı eski kendine özgü davranışlarından ayırt etmek istiyorsanız buna "bağımlılık cehennemi" deyin. Her şeye rağmen, yürütülebilir dosyaları kilitlemeyi varsayılan olarak ayarlamak, paylaşılan bağımlılıkların yönetilmesine yardımcı olmaz . Hiç. Belirli bir dosyaya bağlı olan şeyler, onu yükseltmeye çalıştığınızda çalışmayabilir; ekstra güvenlik yok. Paylaşılan bağımlılıkları olan 2 seçenek vardır: herkes için ücretsiz, çalıştırmayı denediğinizde kırılma riski olan veya bir şeyler yüklemenizi engelleyen paket yöneticisi.
jpmc26

Bu soru, hangi EXE veya DLL'nin kullanılacağına karar vermekle ilgili değil, varsayılan olarak daha sonra ne olacağı ve neden ile ilgili. Tamamen farklı bir konuyu tartışıyorsunuz. Kilitleme, hangi EXE veya DLL'nin çalıştırılacağına karar verildikten sonra, bu örnekte Windows'un kendisi olan ilk kullanıcı tarafından bir düzeyde ek denetim elde etmek ve başkalarına bu denetim hakkında bilgi vermek için kullanılır. Ve "başkalarının" Windows'un ihtiyaç duyduğu dosyaları silmesine veya yazmasına izin vermemek ve bu nedenle onları kilitlememek, elbette ek bir koordinasyon mekanizmasıdır.
Thorsten Schöning

1
Bazı EXE veya DLL'ler büyük olasılıkla "bellekte" değildir, ancak varsayılan olarak onunla eşlenir. Eşleme, dosya içeriğinin kullanılabilir olmasını gerektirir, bu nedenle keyfi olarak değiştirmek varsayılan olarak güvenli değildir ve kişinin ne yaptığını bilmesi gerekir. Açıkçası, kilitli EXE'ler veya DLL'ler şaşırırsa durum böyle değildir. OTOH, diğer tüm dosyalar yalnızca varsayılan olarak kilitlenir, zorunlu değildir, böylece uygulamalar kullanım durumlarına bağlı olarak işlem yazmanıza veya silmenize izin verip vermeyeceklerine karar verebilir. Uygulama geliştiricileri, dosyalarını nasıl kullandıklarını ve hangi işlemlerin ne zaman güvenli olduğunu keyfi kullanıcılardan daha iyi bilmelidir.
Thorsten Schöning

0

NT varyantlarında

dosyaları aç

komut, hangi işlemlerin hangi dosyalar üzerinde tutacağı olduğunu gösterir. Bununla birlikte, sistem global bayrağının 'nesne listesini tut' etkinleştirilmesini gerektirir.

openfiles / local /?

bunu nasıl yapacağınızı ve ayrıca bunu yaptığınızda bir performans cezasına çarptırılacağınızı söyler.


0

Yürütülebilir dosyalar çalıştırıldığında aşamalı olarak belleğe eşlenir. Bunun anlamı, yürütülebilir dosyanın bölümlerinin gerektiği gibi yüklenmesidir. Dosya, tüm bölümler eşlenmeden önce değiştirilirse, büyük kararsızlığa neden olabilir.

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.