Depuis la page de manuel d'epoll:
epoll is a variant of poll(2) that can be used either as an Edge-triggered
or a level-triggered interface
Quand utiliserait-on l'option déclenchée par Edge? La page de manuel donne un exemple qui l'utilise, mais je ne vois pas pourquoi c'est nécessaire dans l'exemple.
Lorsqu'un FD devient prêt à lire ou à écrire, vous ne voudrez pas nécessairement lire (ou écrire) toutes les données immédiatement.
L'epoll déclenché par niveau continuera de vous harceler tant que le FD reste prêt, tandis que le déclenchement par bord ne vous dérangera pas jusqu'à la prochaine fois que vous obtenez un EAGAIN
(il est donc plus compliqué de coder, mais peut être plus efficace selon ce que vous devez faire).
Supposons que vous écrivez d'une ressource vers un FD. Si vous enregistrez votre intérêt pour que ce FD devienne prêt à écrire comme déclenché par niveau, vous recevrez une notification constante que le FD est toujours prêt à écrire. Si la ressource n'est pas encore disponible, c'est un gaspillage de réveil, car vous ne pouvez plus écrire de toute façon.
Si vous deviez l'ajouter en tant que déclencheur Edge à la place, vous recevriez une notification indiquant que le FD était prêt pour l'écriture une fois, puis lorsque l'autre ressource devient prête, vous écrivez autant que vous le pouvez. Ensuite, si write(2)
renvoie EAGAIN
, vous arrêtez d'écrire et attendez la prochaine notification.
La même chose s'applique pour la lecture, car vous ne voudrez peut-être pas extraire toutes les données dans l'espace utilisateur avant d'être prêt à faire tout ce que vous voulez faire avec (donc avoir à le mettre en mémoire tampon, etc.). Avec epoll déclenché par Edge, on vous dit quand il est prêt à lire, puis vous pouvez vous en souvenir et faire la lecture réelle "au fur et à mesure".
Dans mes expériences, ET ne garantit pas qu'un seul thread se réveille, bien qu'il n'en réveille souvent qu'un seul. Le drapeau EPOLLONESHOT est à cet effet.