Quelles sont les différences entre poll et select?

Je fais référence à la norme POSIXselect etpoll appels D'API système C.

144
demandé sur Steven Lu 2009-06-09 19:58:11

2 réponses

Je pense que ce répond à votre question:

De Richard Stevens (rstevens@noao.edu):

La différence fondamentale est que le fd_set de select () est un masque de bits et donc a une certaine taille fixe. Il serait possible pour le noyau de ne limite pas cette taille lorsque le noyau est compilé, permettant application pour définir FD_SETSIZE à ce qu'il veut (comme les commentaires dans l'en-tête du système impliquent aujourd'hui) mais il faut plus de travail. 4.4 BSD noyau et la fonction de bibliothèque Solaris a toutes deux cette limite. Mais Je voyez que BSD / OS 2.1 a maintenant été codé pour éviter cette limite, donc c'est faisable, juste une petite question de programmation. :- ) Quelqu'un devrait déposer un Rapport de bogue Solaris à ce sujet, et voir si elle est jamais corrigé.

, Avec poll(), cependant, l'utilisateur doit allouer un tableau de pollfd structures, et passer le nombre d'entrées dans ce tableau, donc il y a pas de limite fondamentale. Comme le note Casper, moins de systèmes ont poll () que sélectionner, donc, ce dernier est plus portable. Aussi, avec l'original implémentations (SVR3) vous n'avez pas pu définir le descripteur sur -1 pour indiquer le noyau pour ignorer une entrée dans la structure pollfd, ce qui difficile de supprimer les entrées du tableau; SVR4 contourne cela. Personnellement, j'utilise toujours select () et rarement poll (), car je porte mon code aux environnements BSD aussi. Quelqu'un pourrait écrire une implémentation de poll() qui utilise select(), pour ces environnements, mais je n'ai jamais vu un seul. Les deux select () et poll() sont standardisés par POSIX 1003,1 g.

Mise À Jour D'Octobre 2017:

L'e - mail référencé ci-dessus est au moins aussi ancien que 2001; la commande poll() est maintenant (2017) Prise en charge sur tous les systèmes d'exploitation modernes-y compris BSD. En fait, certaines personnes croient que select() doit être désapprouvée. Mis à part les Opinions, les problèmes de portabilité autour de poll() ne sont plus une préoccupation sur les systèmes modernes. De plus, epoll() a depuis été développé (vous pouvez lire la page de manuel ), et continue de gagner en popularité.

Pour le développement moderne, vous ne voulez probablement pas utiliser select(), bien qu'il n'y ait rien de explicitement mal à cela. poll(), et c'est une évolution plus moderne epoll(), fournir les mêmes fonctionnalités (et plus) que select() sans souffrir des limitations qui y sont contenues.

76
répondu akappa 2017-10-18 05:21:03

L'appel select() vous permet de créer trois masques de bits pour marquer les sockets et les descripteurs de fichiers que vous souhaitez surveiller pour la lecture, l'écriture et les erreurs, puis le système d'exploitation marque ceux qui ont effectivement eu une sorte d'activité; poll() vous crée une liste d'ID de descripteur, et le système d'exploitation marque chacun d'eux avec le type d'événement qui s'est produit.

La méthode select() est plutôt maladroite et inefficace.

  1. Il y a généralement plus d'un mille descripteurs de fichiers potentiels disponibles pour un processus. Si un processus de longue durée n'a que quelques descripteurs ouverts, mais qu'au moins l'un d'entre eux a reçu un nombre élevé, alors le masque de bits passé à select() doit être assez grand pour accueillir ce descripteur le plus élevé - de sorte que des plages entières de centaines de bits seront désactivées que le système d'exploitation doit

  2. Une Fois select() retourne, l'appelant a boucle les trois bitmasks pour déterminer quels événements ont eu lieu. Dans de très nombreuses applications typiques, seul un ou deux descripteurs de fichiers obtiendront un nouveau trafic à un moment donné, mais les trois masques de bits doivent être lus jusqu'à la fin pour découvrir quels descripteurs sont.

  3. Parce que le système d'exploitation vous signale l'activité en réécrivant les masques de bits, ils sont ruinés et ne sont plus marqués avec la liste des descripteurs de fichiers que vous voulez écouter. Vous devez reconstruire le masque de bits entier d'une autre liste que vous gardez en mémoire, ou vous devez conserver une copie en double de chaque masque de bits et memcpy() le bloc de données au - dessus des masques de bits ruinés après chaque appel select().

Donc, l'approche poll() fonctionne beaucoup mieux car vous pouvez continuer à réutiliser la même structure de données.

En fait, poll() a inspiré un autre mécanisme dans les noyaux Linux modernes: {[10] } qui améliore encore plus le mécanisme pour permettre un nouveau saut évolutivité, car les serveurs d'aujourd'hui veulent souvent gérer des dizaines de milliers de connexions à la fois. C'est une bonne introduction à l'effort:

Http://scotdoyle.com/python-epoll-howto.html

Bien que ce lien ait de jolis graphiques montrant les avantages de epoll() (vous remarquerez que select() est à ce stade considéré comme si inefficace et démodé qu'il n'obtient même pas une ligne sur ceux-ci graphiques!):

Http://lse.sourceforge.net/epoll/index.html


Update: Voici une autre question de débordement de pile, dont la réponse donne encore plus de détails sur les différences:

Il s'agit de l'un des plus anciens réacteurs de la série.]}

214
répondu Brandon Rhodes 2017-05-23 10:31:35