Dlaczego tylko do odczytu otwiera się określony blok rur?

Zauważyłem kilka dziwnych rzeczy, gdy miałem do czynienia z nazwanymi rurami (FIFO) pod różnymi odmianami Uniksa (Linux, FreeBSD i MacOS X) używającymi Pythona. Pierwszym i być może najbardziej irytującym jest to, że próby otwarcia pustego/bezczynnego FIFO tylko do odczytu będą blokowane (chyba że użyję os.O_NONBLOCK z wywołaniem niższego poziomu os.open()). Jeśli jednak otworzę go do odczytu/zapisu, Nie będę blokował.

Przykłady:

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
Jestem tylko ciekawa dlaczego. Dlaczego otwarte wywołanie blokuje, a nie jakieś kolejne odczyt operacji?

Zauważyłem również, że nieblokujący deskryptor pliku może wykazywać różne zachowania w Pythonie. W przypadku, gdy używam os.open() z os.O_NONBLOCK do początkowej operacji otwierania, wtedy os.read() wydaje się zwracać pusty łańcuch, jeśli dane nie są gotowe na deskryptorze pliku. Jeśli jednak użyję fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK), to os.read wywoła wyjątek (errno.EWOULDBLOCK)

Czy jest jakaś inna flaga ustawiona przez normalną open(), która nie jest ustawiona przez mój przykład os.open()? Czym się różnią i dlaczego?

Author: Tshepang, 2011-04-25

1 answers

Tak to się określa. Ze strony Open Group dla open() function

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.
 68
Author: Jim Garrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-25 20:16:00