• [^] # Re: non-blocking I/O

    Posté par (site web personnel) . En réponse au message Ecritures disques non bloquants. Évalué à 3.

    Ça ne va pas fonctionner : le mode non-bloquant ne marche que pour les tubes (pipes) ou le réseau. Les écritures sur disque sont toujours potentiellement bloquantes, ou pour le dire autrement select te dira toujours « le disque est prêt » (parce qu'effectivement le disque est toujours prêt, il est juste lent).

    Il n'existe pas de solution totalement satisfaisante mais les deux approches classiques sont les suivantes :

    1. Utiliser des entrées/sorties asynchrones (async I/O) : il y a une API POSIX pour ça. La référence avec la GNU libc : http://www.gnu.org/s/hello/manual/libc/Asynchronous-I_002fO.html#Asynchronous-I_002fO. Problème majeur : en fait, ça ne marche pas, ou alors pas très efficacement. Si je ne me trompe pas, la libc utilise des threads par derrière pour l'implémenter, il n'y a pas de support direct du noyau.
    2. Utiliser un fichier mappé en mémoire, avec prefetch : l'idée est d'utiliser mmap pour accéder au fichier comme une zone mémoire, puis madvise(POSIX_MADV_WILLNEED) pour dire qu'on va avoir besoin d'un bout du fichier. Ensuite, mincore permet de savoir si une partie du fichier est en cache, donc si le prefetch demandé par madvise a été honoré, et si tu vas effectivement bloquer. Référence : http://www.gnu.org/s/hello/manual/libc/Memory_002dmapped-I_002fO.html#Memory_002dmapped-I_002fO Problèmes : en théorie madvise et mincore peuvent bloquer, et surtout je ne sais pas si c'est utilisable pour faire des écritures non-bloquantes (je suppose que non). C'est surtout une technique pour les lectures non-bloquantes.

    Dans ton cas, je suppose qu'utiliser les async I/O de POSIX ou mettre en place ton propre thread est la meilleure solution.