Ich habe festgestellt, dass eine Datei, die unter Windows (.exe oder .dll) ausgeführt wird, gesperrt ist und nicht gelöscht, verschoben oder geändert werden kann.
Linux hingegen sperrt die Ausführung von Dateien nicht und Sie können sie löschen, verschieben oder ändern.
Warum sperrt Windows, wenn Linux dies nicht tut? Gibt es einen Vorteil beim Sperren?
windows
linux
operating-system
filesystems
locking
David Lenihan
quelle
quelle
Antworten:
Linux verfügt über einen Referenzzählmechanismus, sodass Sie die Datei während der Ausführung löschen können. Sie bleibt bestehen, solange ein Prozess (der sie zuvor geöffnet hat) über ein offenes Handle verfügt. Der Verzeichniseintrag für die Datei wird beim Löschen entfernt, sodass sie nicht mehr geöffnet werden kann. Prozesse, die diese Datei bereits verwenden, können sie jedoch weiterhin verwenden. Sobald alle Prozesse, die diese Datei verwenden, beendet sind, wird die Datei automatisch gelöscht.
Windows verfügt nicht über diese Funktion, daher muss die Datei gesperrt werden, bis alle von ihr ausgeführten Prozesse abgeschlossen sind.
Ich glaube, dass das Linux-Verhalten vorzuziehen ist. Es gibt wahrscheinlich einige tiefgreifende architektonische Gründe, aber der wichtigste (und einfachste) Grund, den ich am überzeugendsten finde, ist, dass Sie in Windows manchmal eine Datei nicht löschen können, keine Ahnung haben, warum und alles, was Sie wissen, ist, dass ein Prozess sie beibehält verwenden. Unter Linux passiert das nie.
quelle
FILE_SHARE_DELETE
Bit gesetzt ist. Ich glaube nicht, dass der PE-Loader (der EXEs und DLLs lädt) dieses Bit setzt. Die Handles werden als Referenz gezählt und beim Löschen verschwindet die Datei, wenn das letzte Handle gelöscht wird. Der Unterschied zwischen diesem und Unix besteht jedoch darin, dass NT in diesem Fall verhindert, dass eine neue Datei mit demselben Namen erstellt wird.Soweit ich weiß, Linux tut Lock ausführbaren Dateien , wenn sie laufen - es aber die Schlösser Inode . Dies bedeutet, dass Sie die "Datei" löschen können, der Inode sich jedoch noch im Dateisystem befindet, unberührt bleibt und Sie nur einen Link löschen.
Unix-Programme verwenden diese Methode, um ständig über das Dateisystem nachzudenken, eine temporäre Datei zu erstellen, sie zu öffnen und den Namen zu löschen. Ihre Datei ist noch vorhanden, aber der Name wird für andere freigegeben, und niemand anderes kann ihn sehen.
quelle
Linux sperrt die Dateien. Wenn Sie versuchen, eine ausgeführte Datei zu überschreiben, wird "ETXTBUSY" (Textdatei beschäftigt) angezeigt. Sie können die Datei jedoch entfernen, und der Kernel löscht die Datei, wenn der letzte Verweis darauf entfernt wird. (Wenn der Computer nicht sauber heruntergefahren wurde, sind diese Dateien die Ursache für die Meldung "Gelöschter Inode hatte keine d-Zeit", wenn das Dateisystem überprüft wird. Sie wurden nicht vollständig gelöscht, da ein laufender Prozess einen Verweis auf sie hatte. und jetzt sind sie.)
Dies hat einige wesentliche Vorteile: Sie können einen laufenden Prozess aktualisieren, indem Sie die ausführbare Datei löschen, ersetzen und anschließend neu starten. Sogar init kann auf diese Weise aktualisiert werden, die ausführbare Datei ersetzen und ein Signal senden, und es wird selbst erneut ausgeführt (), ohne dass ein Neustart erforderlich ist. (Dies wird normalerweise automatisch von Ihrem Paketverwaltungssystem im Rahmen des Upgrades durchgeführt.)
Unter Windows scheint das Ersetzen einer verwendeten Datei ein großer Aufwand zu sein, der im Allgemeinen einen Neustart erfordert, um sicherzustellen, dass keine Prozesse ausgeführt werden.
Es kann einige Probleme geben, z. B. wenn Sie eine extrem große Protokolldatei haben und diese entfernen. Vergessen Sie jedoch, den Prozess, der in dieser Datei protokolliert wurde, anzugeben, um die Datei erneut zu öffnen. Sie enthält die Referenz, und Sie werden sich fragen warum Ihre Festplatte nicht plötzlich viel mehr freien Speicherplatz bekam.
Sie können diesen Trick auch unter Linux für temporäre Dateien verwenden. Öffnen Sie die Datei, löschen Sie sie und verwenden Sie die Datei weiter. Wenn Ihr Prozess beendet wird (egal aus welchem Grund - auch bei Stromausfall), wird die Datei gelöscht.
Programme wie lsof und fuser (oder einfach nur in / proc // fd herumstöbern) können Ihnen zeigen, bei welchen Prozessen Dateien geöffnet sind, die keinen Namen mehr haben.
quelle
Ich denke, Linux / Unix verwendet nicht die gleiche Sperrmechanik, da sie von Grund auf als Mehrbenutzersystem aufgebaut sind - was die Möglichkeit erwarten würde, dass mehrere Benutzer dieselbe Datei verwenden, möglicherweise sogar für unterschiedliche Zwecke.
Gibt es einen Vorteil beim Sperren? Nun, es könnte möglicherweise die Anzahl der Zeiger reduzieren, die das Betriebssystem verwalten müsste, aber heutzutage ist die Menge an Einsparungen ziemlich vernachlässigbar. Der größte Vorteil, den ich mir beim Sperren vorstellen kann, ist folgender: Sie sparen einige vom Benutzer sichtbare Mehrdeutigkeiten. Wenn Benutzer a eine Binärdatei ausführt und Benutzer b sie löscht, muss die eigentliche Datei so lange bestehen bleiben, bis der Prozess von Benutzer A abgeschlossen ist. Wenn Benutzer B oder andere Benutzer im Dateisystem danach suchen, können sie es nicht finden - es nimmt jedoch weiterhin Speicherplatz ein. Für mich kein großes Problem.
Ich denke, es ist eher eine Frage der Abwärtskompatibilität mit den Dateisystemen von Windows.
quelle
Ich denke, Sie sind zu absolut in Bezug auf Windows. Normalerweise wird kein Swap-Speicherplatz für den Codeteil einer ausführbaren Datei zugewiesen. Stattdessen werden die auslösbaren & DLLs gesperrt. Wenn verworfene Codepages erneut benötigt werden, werden sie einfach neu geladen. Mit / SWAPRUN werden diese Seiten jedoch ausgetauscht. Dies wird für ausführbare Dateien auf CD- oder Netzwerklaufwerken verwendet. Daher muss Windows diese Dateien nicht sperren.
Informationen zu .NET finden Sie unter Schattenkopie .
quelle
Ob ausgeführter Code in einer Datei gesperrt werden soll oder nicht, ist eine Entwurfsentscheidung, und MS hat sich einfach für das Sperren entschieden, da dies in der Praxis klare Vorteile bietet: Auf diese Weise müssen Sie nicht wissen, welcher Code in welcher Version von welcher Anwendung verwendet wird. Dies ist ein großes Problem mit dem Standardverhalten von Linux, das von den meisten Menschen einfach ignoriert wird. Wenn systemweite Bibliotheken ersetzt werden, können Sie nicht leicht erkennen, welche Apps den Code solcher Bibliotheken verwenden. In den meisten Fällen ist das Beste, was Sie erhalten können, dass der Paketmanager einige Benutzer dieser Bibliotheken kennt und sie neu startet. Aber das funktioniert nur für allgemeine und gut bekannte Dinge wie vielleicht Postgres und seine Bibliotheken oder so. Die interessanteren Szenarien sind, wenn Sie Ihre eigene Anwendung für einige Bibliotheken von Drittanbietern entwickeln und diese ersetzt werden, da der Paketmanager Ihre App meistens einfach nicht kennt. Und das' Dies ist nicht nur ein Problem mit nativem C-Code oder Ähnlichem, sondern kann auch bei fast allem auftreten: Verwenden Sie einfach httpd mit mod_perl und einigen Perl-Bibliotheken, die mit einem Paketmanager installiert wurden, und lassen Sie den Paketmanager diese Perl-Bibliotheken aus irgendeinem Grund aktualisieren. Ihr httpd wird nicht neu gestartet, nur weil er die Abhängigkeiten nicht kennt. Es gibt viele Beispiele wie dieses, einfach weil jede Datei möglicherweise Code enthalten kann, der zu jeder Laufzeit im Speicher verwendet wird. Denken Sie an Java, Python und all diese Dinge.
Es gibt also einen guten Grund, die Meinung zu vertreten, dass das Sperren von Dateien standardmäßig eine gute Wahl sein kann. Sie müssen diesen Gründen jedoch nicht zustimmen.
Was hat MS getan? Sie haben einfach eine API erstellt, mit der die aufrufende Anwendung entscheiden kann, ob Dateien gesperrt werden sollen oder nicht. Sie haben jedoch entschieden, dass der Standardwert dieser API darin besteht, der ersten aufrufenden Anwendung eine exklusive Sperre bereitzustellen. Schauen Sie sich die API rund um CreateFile und seine an
dwShareMode
Argumente an. Dies ist der Grund, warum Sie möglicherweise nicht in der Lage sind, Dateien zu löschen, die von einer Anwendung verwendet werden. Ihr Anwendungsfall ist einfach egal, Sie haben die Standardwerte verwendet und daher von Windows eine exklusive Sperre für eine Datei erhalten.Bitte glauben Sie nicht an Leute, die Ihnen etwas über Windows erzählen. Sie verwenden keine Ref-Zählung für GRIFFE oder unterstützen keine Hardlinks oder ähnliches, das ist völlig falsch. Fast jede API, die HANDLEs verwendet, dokumentiert ihr Verhalten in Bezug auf das Ref-Zählen, und Sie können in fast jedem Artikel über NTFS leicht lesen, dass es in der Tat Hardlinks unterstützt und dies immer getan hat. Seit Windows Vista werden auch Symlinks unterstützt, und die Unterstützung für Hardlinks wurde verbessert, indem APIs bereitgestellt wurden, mit denen alle für eine bestimmte Datei gelesen werden können usw. .
Darüber hinaus möchten Sie vielleicht einfach einen Blick auf die Strukturen werfen, die zur Beschreibung einer Datei in z. B. Ext4 verwendet werden, im Vergleich zu denen von NTFS , die viel gemeinsam haben. Beide arbeiten mit dem Konzept von Extents, das Daten von Attributen wie Dateinamen trennt, und Inodes sind so ziemlich nur ein anderer Name für ein älteres, aber ähnliches Konzept. Sogar Wikipedia listet beide Dateisysteme in seinem Artikel auf .
Im Vergleich zu anderen Betriebssystemen im Internet gibt es in Windows wirklich viel FUD beim Sperren von Dateien, genau wie bei der Defragmentierung. Einige dieser FUD können durch einfaches Lesen in der Wikipedia ausgeschlossen werden .
quelle
WinSxS
und so. Außerdem geht es nicht darum, Dinge in den Speicher zu laden und dort zu belassen. Windows macht genau das, wenn nötig, es geht darum zu wissen und zu entscheiden, ob Dateien ersetzt werden sollen oder nicht und wer dafür verantwortlich ist. Die Windows-API lässt einfach den ersten Benutzer der Datei entscheiden, und das ist sehr sinnvoll.NT-Varianten haben die
offene Dateien
Befehl, der anzeigt, welche Prozesse Handles für welche Dateien haben. Es ist jedoch erforderlich, das globale Systemflag "Objektliste verwalten" zu aktivieren.
openfiles / local /?
erklärt Ihnen, wie dies zu tun ist und dass dadurch eine Leistungseinbuße entsteht.
quelle
Ausführbare Dateien werden beim Ausführen schrittweise dem Speicher zugeordnet. Dies bedeutet, dass Teile der ausführbaren Datei nach Bedarf geladen werden. Wenn die Datei vor dem Zuordnen aller Abschnitte ausgelagert wird, kann dies zu einer erheblichen Instabilität führen.
quelle