web-dev-qa-db-ja.com

名前付きパイプブロックを読み取り専用で開くのはなぜですか?

Pythonを使用してUNIXのさまざまなフレーバー(Linux、FreeBSD、MacOS X)で名前付きパイプ(FIFO)を処理するときに、いくつかの奇妙な点に気付きました。最初の、そしておそらく最も厄介なのは、空/アイドルを開こうとするとFIFO読み取り専用がブロックされることです(_os.O_NONBLOCK_を下位レベルos.open()で使用しない限り)ただし、読み取り/書き込み用に開いた場合、ブロッキングは発生しません。

例:

_f = open('./myfifo', 'r')               # Blocks unless data is already in the pipe
f = os.open('./myfifo', os.O_RDONLY)    # ditto

# Contrast to:
f = open('./myfifo', 'w+')                           # does NOT block
f = os.open('./myfifo', os.O_RDWR)                   # ditto
f = os.open('./myfifo', os.O_RDONLY|os.O_NONBLOCK)   # ditto
_

なぜか興味があります。後続の読み取り操作ではなく、オープンコールがブロックするのはなぜですか?

また、非ブロッキングファイル記述子がPythonのさまざまな動作を示す可能性があることに気付きました。最初のオープニング操作に_os.O_NONBLOCK_でos.open()を使用する場合、ファイル記述子でデータの準備ができていない場合、os.read()は空の文字列を返すようです。ただし、fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK)を使用すると、_os.read_で例外が発生します(_errno.EWOULDBLOCK_)

open()の例では設定されていない通常のos.open()で設定されている他のフラグはありますか?それらはどのように違い、なぜですか?

57
Jim Dennis

それが定義された方法です。 open() 関数のOpen Groupページから

O_NONBLOCK

    When opening a FIFO with O_RDONLY or O_WRONLY set: If O_NONBLOCK is
    set:

        An open() for reading only will return without delay. An open()
        for writing only will return an error if no process currently
        has the file open for reading.

    If O_NONBLOCK is clear:

        An open() for reading only will block the calling thread until a
        thread opens the file for writing. An open() for writing only
        will block the calling thread until a thread opens the file for
        reading.
70
Jim Garrison