2016-02-06 1 views
0

Comment utilise-t-on réellement kqueue() pour faire des r/w asynchrones simples? Il semble que ce soit pour remplacer epoll() et select(), et donc le problème qu'il essaye de résoudre est la mise à l'échelle de l'écoute sur un grand nombre de descripteurs de fichiers pour les changements.Utilisation de kqueue pour une async simple io

Cependant, si je veux faire quelque chose comme: lire les données de descripteur X, laissez-moi quand les données sont prêtes - comment l'API support qui? À moins qu'il n'y ait une API complémentaire pour lancer des requêtes r/w non-bloquantes, je ne vois pas d'autre moyen que de gérer moi-même un pool de threads, ce qui va à l'encontre du but recherché.

Est-ce simplement le mauvais outil pour le travail? Stick avec aio?

En plus: Je ne suis pas avertis avec la façon dont OS BSD internes modernes fonctionnent - mais est kqueue() construit sur aio ou visa versa? J'imagine que cela dépendrait de savoir si le système de sous-système OS io est fondamentalement basé sur l'interruption ou l'interrogation.

Répondre

0

Aucune des API que vous mentionnez, à part aio elle-même, n'a quoi que ce soit à voir avec des E/S asynchrones.

Aucun select(), poll(), epoll() ou kqueue() sont utiles pour la lecture des systèmes de fichiers (ou "vnodes"). Les descripteurs de fichier pour les éléments du système de fichiers sont toujours "prêts", même si le système de fichiers est monté sur le réseau et qu'il y a une latence du réseau telle qu'une lecture bloquerait réellement pendant un temps significatif. Votre seul choix pour éviter le blocage est aio ou, sur une plate-forme avec GCD, envoyer les E/S. L'utilisation de kqueue() et similaires est pour d'autres types de descripteurs de fichiers tels que des sockets, des tuyaux, etc. où le noyau maintient des tampons et il y a un "événement" (comme l'arrivée d'un paquet ou une écriture sur un tuyau) qui change lorsque les données sont disponibles. Bien sûr, kqueue() peut également surveiller une variété d'autres sources d'entrée, comme les ports Mach, processus, etc.

(Vous pouvez utiliser kqueue() pour les lectures de vnodes, mais il ne vous indique quand la position du fichier est au Donc, vous pouvez l'utiliser pour être informé quand un fichier a été étendu ou tronqué Cela ne veut pas dire qu'une lecture ne bloque pas.)

Je ne pense pas non plus kqueue() ou aio construit de l'autre. Pourquoi penseriez-vous qu'ils étaient?

+0

Merci pour la réponse. Quand j'ai dit «descripteurs», je l'ai dit dans son sens général, bien que de toute évidence, il ait été conçu pour cibler les prises/tuyaux.Je ne sais pas pourquoi je pensais qu'ils seraient construits les uns les autres - pas que j'y pense, ça n'aurait aucun sens. Il est probable qu'ils soient tous les deux construits à partir d'une structure au niveau du noyau, dans laquelle les threads peuvent s'inscrire pour être intéressés par un événement, et informés quand cela arrive. La différence serait 'kqueue()' paquets ensemble, tandis que 'aio' prendrait la propriété exclusive d'un descripteur et lancerait une requête r/w en premier. Oui? –

+0

Sûrement kqueue prend en charge les E/S asynchrones via le filtre EVFILT_AIO. Vous configurez une file d'attente, puis lorsque vous effectuez une requête d'E/S asynchrone, vous transmettez le descripteur de la file d'attente dans la requête et, une fois l'opération terminée, un événement est envoyé à la file d'attente. Cela semble exactement ce que veut le PO. Est-ce que je manque quelque chose? –

+1

@TomAnderson, sur macOS au moins, la page de manuel 'kqueue' le dit pour' EVFILT_AIO': "Ce filtre est actuellement non supporté." –

0

J'ai utilisé kqueues pour adapter un serveur proxy Linux (basé sur epoll) à BSD. J'ai mis en place des files d'attente asynchrones GCD séparées, chacune utilisant une kqueue pour écouter sur un ensemble de sockets. GCD gère les threads pour vous.

+0

Merci pour la réponse. Quand je mentionne moi-même la gestion d'un pool de threads, je ne le fais pas parce que c'est trop difficile - juste que c'est potentiellement inutile si un véritable mécanisme d'API et une API existaient. Je ne vois pas le point dans l'utilisation d'une API feint juste non-bloquant en émettant un appel de blocage sur un fil séparé - pas de véritable raison de ne pas simplement écrire vous-même. –

+0

kqueue/kevent est un mécanisme de blocage. C'est pourquoi il a un paramètre d'attente. Je suppose qu'il est destiné à être utilisé à partir d'un fil de fond/threads. Il ne «feint pas de blocage» du tout. –