0

最近、私たちの環境 AIX 7.1 で興味深いことを観察していました。この問題を追跡するために、Java で小さなロック アプリケーションを作成しました。

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;

public class Locker {

    public static void main(String[] args) throws Exception {
        File file = new File("/etc/passwd");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
        FileLock lock;

        try {
            lock = channel.tryLock();

            if (lock != null) {
                System.out.println("I have the lock");
                while(true) {}
            }

        } catch (OverlappingFileLockException e) {
            e.printStackTrace();
        }

    }
}

私が知る限り、これは /etc/passwd で読み取り/書き込みロックを取得します。このアプリケーションの 2 つのインスタンスを実行しようとすると、予想どおり 1 つのインスタンスでしかロックを取得できません。同様に、次のコマンドを実行すると:

su user2 -c echo test

Java アプリケーションからロックを解放するまで、コマンドがハングします。一方、ファイルを次のように読み取ります。

cat /etc/passwd

正常に実行されます。そして、次のようにファイルに書き込むことさえできます:

cat /etc/passwd > /etc/passwd

も大丈夫です。明らかに、Java FileLock の実装はシステムに依存しており、この性質のために指定された動作はありません。しかし、私が興味を持っているのは、「su」が待機する必要がある理由です。「cat」リダイレクトが単にファイルを削除し、新しい出力で再作成する可能性はありますか?それとも、コマンド間でロックメカニズムが一貫していないだけですか?

編集:質問をして以来、Javaアプリケーションにいくつかの書き込みステートメントを追加したため、プログラムの構造は次のようになりました。

Acquire Java Lock on /etc/passwd
IO-Redirect with a small change to /etc/passwd
Append some text to /etc/passwd in the Java application

そして、このすべての情報が更新された /etc/passwd に反映されているため、IO-Redirection は単にファイルを削除していたわけではないようです。では、なぜ 'su' と '>' の違い (そしておそらく他の多くのもの) なのですか?

4

1 に答える 1

2

UNIX でのファイル ロックは推奨事項であり、必須ではありません。つまり、ロックは完全に独立しており、ファイルを読み書きしようとしている人には影響しません。ロックを取得しようとする他のプログラムとのみ対話します。

catと リダイレクトはファイルをロックしようとしないため、ロックはそれらに影響を与えません 。su一方、 /etc/passwd を読み取る前にロックするため、ロックを保持しているプログラムは、ロックを解放するまで (ロックの取得を) 待機させます。

于 2013-02-12T18:10:22.310 に答える