web-dev-qa-db-fra.com

Pourquoi une ouverture en lecture seule d'un bloc de canaux nommé?

J'ai remarqué quelques bizarreries lors du traitement des canaux nommés (FIFO) sous différentes versions d'UNIX (Linux, FreeBSD et MacOS X) en utilisant Python. Le premier, et peut-être le plus ennuyeux, est que les tentatives d'ouverture d'un espace vide/inactif FIFO en lecture seule se bloqueront (sauf si j'utilise os.O_NONBLOCK Avec le niveau inférieur os.open() call). Cependant, si je l'ouvre en lecture/écriture, je n'obtiens aucun blocage.

Exemples:

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

Je suis juste curieux de savoir pourquoi. Pourquoi l'appel ouvert bloque-t-il plutôt qu'une opération de lecture ultérieure?

J'ai également remarqué qu'un descripteur de fichier non bloquant peut présenter différents comportements en Python. Dans le cas où j'utilise os.open() avec le os.O_NONBLOCK Pour l'opération d'ouverture initiale alors une os.read() semble retourner une chaîne vide si les données ne sont pas prêtes sur le fichier descripteur. Cependant, si j'utilise fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK) alors un os.read Déclenche une exception (errno.EWOULDBLOCK)

Y a-t-il un autre indicateur défini par la open() normale qui n'est pas défini par mon os.open() exemple? En quoi sont-ils différents et pourquoi?

57
Jim Dennis

C'est juste ainsi que c'est défini. Depuis la page Open Group pour la fonction open()

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