私の例はMinecraftです。 LinuxでBukkitを実行するときは、/ pluginsフォルダから.jarファイルを削除または更新してから、単に「reload」コマンドを実行できます。
Windowsでは、.jarファイルを削除または置き換えようとすると、そのファイルが現在使用中であるというメッセージが表示されるため、サーバープロセス全体を終了する必要があります。
私にとっては良いことですが、なぜこれが起こるのですか?ここでLinuxは何を変えていますか?
答え1
Linuxがファイルを削除する方法は、Windowsとはまったく異なります。まず、* unix基本ファイルシステムでファイルを管理する方法の簡単な説明です。
ファイルはという名前のマルチレベル構造でディスクに保存されますi-node
。各iノードは単一のファイルシステムで一意の番号を持ちます。 iノード構造は、ファイルサイズ、ファイルに割り当てられたデータブロックなどのファイルに関するさまざまな情報を保持しますが、この質問に答えるために最も重要なデータ要素は、ファイルの履歴を保持するファイルですlink counter
。directories
各レコードには、参照する inode 番号、ファイル名の長さ、およびファイル名自体があります。このスキームを使用すると、「ポインタ」、つまり異なる名前を持つ別の場所にある同じファイルへの「リンク」を持つことができます。 iノードのリンクカウンタは、実際にそのiノードを参照するリンクの数を格納します。
プロセスでファイルを開くとどうなりますか?まず、open()
関数はファイルレコードを検索します。次に、対応するiノードのメモリにiノード構造がすでに存在することを確認します。一部のアプリケーションでこのファイルが開いている場合、これが発生する可能性があります。それ以外の場合、システムは新しいメモリiノード構造を初期化します。その後、システムはメモリ内のinode構造のオープンカウンタをインクリメントし、対応するファイル記述子をアプリケーションに返します。
ファイルを削除するためのLinuxライブラリ呼び出しと呼ばれますunlink
。この関数はディレクトリからファイルレコードを削除し、iノードのリンクカウンタを減らします。システムが inode 構造体がメモリーに存在し、対応するオープン・カウンターがゼロでないことを検出すると、この呼び出しはアプリケーションに制御を戻します。それ以外の場合は、リンクカウンタが0に達したことを確認し、そうである場合、システムはinodeとinode自体に割り当てられているすべてのブロックを解放し、それをアプリケーションに返します。
アプリケーションがファイルを閉じるとどうなりますか?この関数はclose()
オープンカウンタを減らし、その値をチェックします。値がゼロでない場合、関数はアプリケーションに返されます。それ以外の場合は、iノードリンクカウンタが0であることを確認してください。 0 の場合、ファイル内のすべてのブロックと inode がアプリケーションに返される前に解放されます。
このメカニズムを使用すると、ファイルが開いている間に「削除」できます。同時に、ファイルを開いたアプリケーションは引き続きファイルのデータにアクセスできます。したがって、あなたの例では、JREはまだファイルバージョンを開いたままにし、ディスクには別の最新バージョンがあります。
また、この機能を使用すると、通常の動作を中断することなく、システム上のglibc(libc)(すべてのアプリケーションのコアライブラリ)を更新できます。
Windows
20年前だけでも、私たちはFAT以外にDOSの他のファイルシステムを知りませんでした。これらのファイルシステムは構造と管理の原則が異なります。これらの原則は、ファイルが開いている間にファイルを削除することを許可しないため、DOSと最近では、Windowsは開いたファイルに対する削除要求を拒否する必要があります。 NTFSは* nixファイルシステムと同じ動作を許可できますが、Microsoftはファイル削除の慣例的な動作を維持することにしました。
これが答えです。短くはありませんが、今アイデアができました。
編集するWin32
:混乱の原因についてよく読んだ。https://web.archive.org/web/20190218083407/https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
@ジョンありがとう