Windows(.exeまたは.dll)でファイルを実行すると、ファイルがロックされ、削除、移動、または変更できないことに気付きました。
一方、Linuxは実行中のファイルをロックせず、ユーザーはそれらを削除、移動、または変更できます。
LinuxがロックしないのにWindowsがロックするのはなぜですか?ロックすることに利点はありますか?
Linuxには参照カウントメカニズムがあるため、実行中にファイルを削除できます。ファイルのハンドルが開いているプロセス(以前に開いたプロセス)がある限り、ファイルは存続します。ファイルを削除すると、ファイルのディレクトリエントリが削除されるため、それ以上開くことはできませんが、このファイルをすでに使用しているプロセスは引き続き使用できます。このファイルを使用するすべてのプロセスが終了すると、ファイルは自動的に削除されます。
Windowsにはこの機能がないため、ファイルから実行されているすべてのプロセスが終了するまで、ファイルを強制的にロックします。
Linuxの動作が望ましいと思います。おそらくいくつかの深いアーキテクチャ上の理由がありますが、私が最も説得力があると思う主な(そして単純な)理由は、Windowsではファイルを削除できないことがあり、その理由がわからず、何らかのプロセスがファイルを保持していることだけです使用する。 Linuxではそれは決して起こりません。
私の知る限り、Linuxは実行中の実行可能ファイルをロックします。ただし、実行可能ファイルはロックします inode 。これは、「ファイル」を削除できるが、iノードはファイルシステム上にあり、変更されておらず、実際に削除したのはリンクだけであることを意味します。
Unixプログラムは、ファイルシステムについて常にこの考え方を使用し、一時ファイルを作成して開き、名前を削除します。あなたのファイルはまだ存在しますが、名前は他の人が使用できるように解放され、他の人はそれを見ることができません。
Linuxはファイルをロックします。実行中のファイルを上書きしようとすると、「ETXTBUSY」(テキストファイルがビジー)になります。ただし、ファイルを削除することはできます。カーネルは、ファイルへの最後の参照が削除されたときにファイルを削除します。 (マシンが正常にシャットダウンされなかった場合、これらのファイルは、ファイルシステムがチェックされたときに「削除されたiノードのd-timeがゼロでした」メッセージの原因です。実行中のプロセスがそれらを参照していたため、完全には削除されませんでした。そして今、彼らはそうです。)
これにはいくつかの大きな利点があります。実行可能ファイルを削除して置き換え、プロセスを再起動することで、実行中のプロセスをアップグレードできます。 initでさえ、このようにアップグレードし、実行可能ファイルを置き換えてシグナルを送信することができ、再起動せずにそれ自体を再実行します。 (これは通常、アップグレードの一部としてパッケージ管理システムによって自動的に行われます)
Windowsでは、使用中のファイルを置き換えることは大きな問題のように思われ、通常、プロセスが実行されていないことを確認するために再起動が必要です。
非常に大きなログファイルがあり、それを削除したが、そのファイルにログを記録していたプロセスにファイルを再度開くように指示するのを忘れると、参照が保持され、不思議に思うなど、いくつかの問題が発生する可能性があります。ディスクが突然多くの空き領域を取得しなかった理由。
Linuxで一時ファイルにこのトリックを使用することもできます。ファイルを開いて削除してから、引き続きファイルを使用してください。プロセスが終了すると(理由が何であれ、電源障害であっても)、ファイルは削除されます。
Lsofやfuserのようなプログラム(または/ proc // fdをざっと見て回る)は、名前がなくなったファイルを開いているプロセスを表示できます。
あなたはWindowsについて絶対的すぎると思います。通常、実行可能ファイルのコード部分にスワップスペースを割り当てません。代わりに、実行可能およびDLLをロックします。破棄されたコードページが再度必要になった場合は、単に再読み込みされます。ただし、/ SWAPRUNを使用すると、これらのページはスワップ状態に保たれます。これは、CDまたはネットワークドライブ上の実行可能ファイルに使用されます。したがって、Windowsはこれらのファイルをロックする必要はありません。
.NETの場合は、 シャドウコピー を参照してください。
Linux/unixは、マルチユーザーシステムとしてゼロから構築されているため、同じロックメカニズムを使用していないと思います。これにより、複数のユーザーが同じファイルを使用する可能性があります。
ロックすることに利点はありますか?そうですね、OSが管理しなければならないポインタの量を減らすことができるかもしれませんが、今日では節約の量はごくわずかです。ロックすることで私が考えることができる最大の利点はこれです:ユーザーが見ることができる曖昧さをいくらか節約できます。ユーザーaがバイナリファイルを実行していて、ユーザーbがそれを削除した場合、実際のファイルはユーザーAのプロセスが完了するまでそのままにしておく必要があります。それでも、ユーザーBまたは他のユーザーがファイルシステムでファイルを探すと、ファイルシステムを見つけることができませんが、スペースを占有し続けます。私にとってはそれほど大きな懸念ではありません。
主に、ウィンドウのファイルシステムとの下位互換性に関する問題だと思います。
ファイル内の実行されたコードをロックする必要があるかどうかは設計上の決定であり、実際には明らかな利点があるため、MSは単にロックすることを決定しました。そうすれば、どのバージョンのどのコードがどのアプリケーションで使用されているかを知る必要がありません。これはLinuxのデフォルトの動作に関する大きな問題であり、ほとんどの人が単に無視しています。システム全体のライブラリが置き換えられた場合、どのアプリがそのようなライブラリのコードを使用しているかを簡単に知ることはできません。ほとんどの場合、パッケージマネージャーがそれらのライブラリの一部のユーザーを認識して再起動するのが最善です。しかし、それは一般的でよく知られているPostgresとそのライブラリなどでのみ機能します。より興味深いシナリオは、いくつかのサードパーティライブラリに対して独自のアプリケーションを開発し、それらが置き換えられる場合です。ほとんどの場合、パッケージマネージャーは単にアプリを認識していないためです。そして、それはネイティブCコードなどの問題だけでなく、ほとんどすべてで発生する可能性があります。mod_Perlでhttpdを使用し、パッケージマネージャーを使用してインストールされたいくつかのPerlライブラリを使用し、何らかの理由でパッケージマネージャーにそれらのPerlライブラリを更新させます。依存関係がわからないという理由だけで、httpdは再起動しません。このような例はたくさんあります。ファイルには、実行時にメモリ内で使用されているコードが含まれている可能性があるためです。Java、Pythonなど)について考えてみてください。
したがって、デフォルトでファイルをロックするのが良い選択かもしれないという意見を持つのには十分な理由があります。ただし、その理由に同意する必要はありません。
では、MSは何をしましたか?彼らは、呼び出し元のアプリケーションにファイルをロックするかどうかを決定する機会を与えるAPIを作成しただけですが、このAPIのデフォルト値は、最初の呼び出し元のアプリケーションに排他ロックを提供することであると判断しました。 CreateFile とそのdwShareMode
引数に関するAPIを見てください。これが、一部のアプリケーションで使用中のファイルを削除できない場合がある理由です。ユースケースを気にせず、デフォルト値を使用したため、Windowsによってファイルの排他ロックが取得されました。
Windowsについて何かを言っている人が、ハンドルをカウントする参照を使用していない、またはハードリンクなどをサポートしていないと信じないでください。これは完全に間違っています。 HANDLEを使用するほとんどすべてのAPIは、参照カウントに関する動作を文書化しており、実際にはハードリンクをサポートし、常にサポートしているNTFSに関するほぼすべての記事を簡単に読むことができます。 Windows Vista以降、シンボリックリンクもサポートされており、ハードリンクのサポートは、APIを 特定のファイルのすべてを読み取る などに提供することで改善されています。
さらに、ファイルの記述に使用される構造を確認したい場合もあります。 Ext4[〜#〜] ntfs [〜#〜] と比較すると、多くの共通点があります。どちらも、データをファイル名などの属性から分離するエクステントの概念で機能します。iノードは、古いが類似した概念のほぼ別の名前です。ウィキペディアでさえ、両方のファイルシステムを 記事 にリストしています。
デフラグと同じように、ネット上の他のOSと比較して、Windowsのファイルロックには本当に多くのFUDがあります。このFUDの一部は、 Wikipedia を少し読むだけで除外できます。
実行可能ファイルは、実行時にメモリに段階的にマップされます。つまり、実行可能ファイルの一部が必要に応じてロードされます。すべてのセクションがマップされる前にファイルがスワップアウトされると、重大な不安定性が発生する可能性があります。
NTバリアントには
openfiles
コマンド。どのプロセスがどのファイルにハンドルを持っているかを示します。ただし、システムグローバルフラグ 'オブジェクト一覧の更新'を有効にする必要があります。
openfiles/local /?
これを行う方法と、そうすることでパフォーマンスの低下が発生することも説明します。