2010-11-13 18 views
3

Mon application va envoyer énormément de données sur le réseau, j'ai donc décidé (parce que j'utilise Linux) d'utiliser epoll et splice. Voici comment je vois (pseudo-code):Question sur epoll et splice

epoll_ctl (file_fd, EPOLL_CTL_ADD); // waiting for EPOLLIN event 
while(1) 
{ 
    epoll_wait (tmp_structure); 

    if (tmp_structure->fd == file_descriptor) 
    { 
     epoll_ctl (file_fd, EPOLL_CTL_DEL); 
     epoll_ctl (tcp_socket_fd, EPOLL_CTL_ADD); // wait for EPOLLOUT event 
    } 

    if (tmp_structure->fd == tcp_socket_descriptor) 
    { 
     splice (file_fd, tcp_socket_fd); 
     epoll_ctl (tcp_socket_fd, EPOLL_CTL_DEL); 
     epoll_ctl (file_fd, EPOLL_CTL_ADD); // waiting for EPOLLIN event 
    } 
} 

Je suppose que ma demande va ouvrir jusqu'à 2000 sockets TCP. Je veux vous poser deux questions:

  1. Il y aura beaucoup d'appels epoll_ctl, ne sera pas lent quand je vais avoir autant de sockets?
  2. Le descripteur de fichier doit d'abord être lisible et il y aura un certain intervalle avant que le socket devienne accessible en écriture. Puis-je être sûr que, au moment où le socket devient accessible en écriture, le descripteur de fichier est toujours lisible (pour éviter de bloquer l'appel)?

Répondre

2

1ère question

  1. Vous pouvez utiliser déclenché par front plutôt que vous avez donc ne vote même pas supprimer déclenché la prise à chaque fois.
  2. Vous pouvez utiliser EPOLLONESHOT pour empêcher la prise de retirer

descripteur de fichier doit être lisible première et il y aura un certain intervalle avant la prise deviendra accessible en écriture.

Quel type de descripteur de fichier? Si ce fichier sur le système de fichiers vous ne pouvez pas utiliser select/poll ou d'autres outils à cette fin, le fichier sera toujours lisible ou inscriptible quel que soit l'état du disque et du cache. Si vous avez besoin de faire du personnel asynchrone, vous pouvez utiliser l'API aio_*, mais en général il suffit de lire le fichier dans le fichier et de supposer qu'il n'est pas bloquant.

S'il s'agit d'un socket TCP, il devrait être inscriptible la plupart du temps. Il est préférable d'utiliser appels non bloquants et de mettre des sockets à epoll lorsque vous obtenez EWOULDBLOCK.

+0

Par 'file_descriptor' je veux dire descripteur de fichier disque ouvert avec open() syscall, de manière à voir mon idée cloud fonctionner correctement :) – Goofy

+0

@Goofy, vous ne pouvez pas utiliser select/epoll avec des disques dans le fichier car ils signalerait toujours lisibilité/écriture même si l'opération peut bloquer pour amener des données du disque. Voir http://www.kegel.com/c10k.html – Artyom

1

Envisager d'utiliser le drapeau EPOLLET. C'est certainement pour ce cas. Lorsque vous utilisez ce drapeau, vous pouvez utiliser la boucle d'événements de manière appropriée sans désenregistrer (ou modifier le mode) des descripteurs de fichiers depuis la première inscription dans epoll. :) prendre plaisir!