7
votes

Socket Server avec Epoll and Threads

J'essaie de créer un serveur de socket en C pour un éditeur en temps réel collaboratif http: / /en.wikipedia.org/wiki/collaborative_real-time_editor Mais je ne sais pas quelle est la meilleure architecture de serveur pour elle.

Au début, j'essayais d'utiliser Sélectionner pour le serveur de socket, mais après cela, je lisais à propos de Epoll et je pense maintenant que l'époll est le meilleur choix car le client enverra chaque lettre, que l'utilisateur écrira Textarea, sur le serveur, le serveur aura donc une allocation de données à traiter.

En outre, je veux utiliser des threads avec Epoll, mais je ne sais pas exactement comment les utiliser. Je veux utiliser des threads parce que je pense que c'est mieux utiliser 2 ou tous les CPU sur la machine cible.

mon plan est

  • créer 2 threads lorsque le serveur démarre

  • premier thread va analyser les nouveaux clients et les préparera à lire ou à envoyer

  • Le deuxième thread aura le travail de lire et d'envoyer des données de / vers des clients

    Le problème est que ces 2 threads utiliseront un moment (1) avec une epoll_wait.

    Mes questions sont, est-ce une bonne architecture de serveur pour utiliser Epoll avec des threads? Sinon, quelles options j'ai?

    edit: Je ne peux pas utiliser libevent ou libev ou d'autres bibliothèques parce que c'est un projet collégial et je ne peux pas permettre de Utilisez des bibliothèques externes.


2 commentaires

Je conseillerais d'utiliser Epoll sur les points de ne pas être universellement disponible et que vous commencez avec quelque chose de simple tout en déterminant l'architecture. De plus, Epoll est bon si vous avez un grand nombre de connexions, mais cela ne comporte pas vraiment de temps de réponse lorsque vous n'avez que quelques connexions.


Sauf si vous avez réussi à saturer un noyau de la CPU, il n'y a aucune raison d'être multipliée. Et pour cela, vous avez besoin de clients de 10k (si votre application est bien écrite).


3 Réponses :


3
votes

Vous voudrez peut-être envisager d'utiliser quelque chose comme libev ou libtevent au lieu d'écrire votre propre événement de manutention de la mise en œuvre. Celles-ci vous donnent un gestionnaire d'événements multiplateformes qui utilisera tout ce qui est approprié (que ce soit SELECT , sondage , EPOLL , KQQUUE < / code> ou quoi que ce soit d'autre) et le plus probablement à une hauteur générale inférieure à celle de deux threads qui remettent le travail l'un à l'autre.


5 commentaires

Comment Libeven ou Libev peut-il ensuite être utilisé pour utiliser tous les processeurs disponibles? Y a-t-il un moyen standard de faire cela?


@Slappythefish: Pour ce que je comprends de la charge de travail, cela ne serait probablement pas nécessaire. Même une implémentation assez naïf fonctionnerait probablement car il s'agit principalement d'E / S Lié. En outre, en supposant que TCP, la question de chaque lettre étant envoyée séparément n'existe pas vraiment (sauf obligation forcée, par exemple en utilisant tcp_nodelay ou similaire).


@HASTURKUN J'ai oublié de mentionner sur mon message principal, je ne peux pas utiliser libevent ou libev, car il s'agit d'un projet collégial et je ne permet pas d'utiliser des bibliothèques externes.


@ Bugspy.net Ils nous enseignent que la plaine C Par exemple, c'était l'année où ils ont ajouté Epoll, au cours des dernières années, il n'existait aucune mention sur l'Epoll uniquement et sonder. :)


@CEMYCC: Un simple serveur fileté unique fonctionnerait probablement assez bien pour ce cas, à moins que vous n'ayez besoin de faire autrement. Vous pouvez utiliser le même SELECT ou BOUCLE Pour accepter les nouvelles connexions et pour envoyer / recevoir des données des sockets connectés. Je vous suggère de définir vos prises pour être non bloquantes pour empêcher certaines surprises (par exemple, SELECT indique Recv ne bloquera pas, mais un Recv Les blocs, qui peuvent arriver pour UDP)



3
votes

Il suffit de commencer à utiliser libevent ou libev et suivez leurs exemples. Il existe de nombreux exemples - n'essayez pas d'inventer quoi que ce soit de nouveau ici


1 commentaires

Parfois, essayez de le faire vous-même peut faire comprendre aux excréties d'un système et apprécier la facilité d'utilisation d'une API de plus, tout en diminuant également les surprises possibles que l'on obtient lors de l'utilisation d'une API de niveau supérieur. S'il s'agit d'un projet collégial, je dirais aller pour le sondage brut / Select / Epoll!



7
votes

Je pense que vous essayez de sur-ingénieur ce problème. L'architecture Epoll de Linux était destinée aux situations où vous avez des milliers de connexions simultanées. Dans ce type de cas, la surcharge de la manière dont les appels système et SELECT sont définis seront le goulot d'étranglement principal sur un serveur. La décision d'utiliser sondage ou Sélectionnez vs. code> Epoll est basé sur le nombre de connexions, pas la quantité de données.

Pour ce que vous faites, il semble que les humains de votre système d'édition se produiraient une insane après avoir frappé quelques dizaines d'éditeurs simultanés. Utiliser Epoll vous fera probablement devenir fou; Ils jouent quelques astuces avec l'API pour faire pression sur les performances supplémentaires et vous devez faire très attention au traitement des informations que vous recevez des appels.

Ce type d'application sonne comme s'il serait Network-i / O-liée au lieu de la CPU-liée. Je voudrais essayer d'écrire comme un serveur à un seul filetage avec sondage en premier. Lorsque vous recevez un nouveau texte, la mémoire tampon pour vos clients si nécessaire, puis envoyez-la lorsque la prise accepte écrire appels. Utiliser des E / S non bloquantes; Le seul appel que vous souhaitez bloquer est le appel appel.

Si vous effectuez une quantité importante de traitement sur les données après la réception, mais avant de l'envoyer des clients, vous pourriez bénéficier d'un multi-threading. Écrivez d'abord la version à une seule-thread. Si vous êtes limité CPU (Vérifiez à l'aide de TOP ) et la majeure partie du temps de la CPU est dépensée dans les fonctions où vous effectuez un traitement de données (vérification à l'aide de GPROF ), ajoutez de multithreading pour effectuer le traitement des données.

Si vous le souhaitez, vous pouvez utiliser des tuyaux ou des prises de domaine UNIX à l'intérieur du programme pour la communication entre les différents threads - - de cette manière tout dans le thread principal et manipulé via sondage . Sinon, avec ce modèle, vous pouvez même utiliser plusieurs processus avec Fourche au lieu de plusieurs threads.


0 commentaires