IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

gestion socket process votre avis


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Points : 41
    Points
    41
    Par défaut gestion socket process votre avis
    Bonjour à tous.


    Je suis dans le cadre d'un process qui accepte une grande quantité de connections socket persistente (plus de 2000). Ce process devra gerer tout un tas de chose de façon continu et independament des clients connectés. En plus de ça, bien sur il devra gerer les clients et leurs interractions les uns avec les autres.

    J'ai donc choisis d'eviter de bosser avec des thread qui m'obligeraient à gerer des mutex ou autres semaphores qui sont souvent source de galere. D'autre part je prefere eviter de creer 2000 thead si 2000 clients. Je suis donc sur un seul process, mais j'ai prevu la possibilité d'en lancer d'autre identiques et qu'ils soient tous liés les un aux autre via INET_UNIX socket pour permettre la com entre client si besoin.

    Reste à savoir comment gerer les evenements socket. Actuellement je suis partis sur des sockets non bloquant sur une boucle qui fait ceci :

    traitements divers necessitant plus ou moins de passages dans la boucle
    accept() sur le socket
    boucle sur tous les clients pour faire :
    recv() // si <0 rien à lire, si ==0 deco du client sinon lire message et traiter
    send() si ya qq chose à envoyer (avec gestion de buffer plein etc..)

    Ma boucle générale fait une pause avec usleep de 500 µsec (en dessous je bouffe du cpu) moins le temps passé à traiter la passe. Donc à vide mon cpu tourne à 1% et en pleine charge il tournera à 100%.

    Le defaut c'est que d'une part je ne lis/accept/send les messages que toutes les 500µsec au mieux (mais bon ça à la rigueur c'est pas grave). Mais surtout que je suis obligé de parcourir la liste de tous mes clients pour faire le recv non bloquant.

    Si je me tourne vers poll() je suis obligé de parcourir tous les fd (ce qui revient à parcourir tous les clients et à faire un recv). Ensuite d'apres le fd qui à un event, je dois retrouver mon objet client associé (eventuellement table de hash ?).

    L'idéal aurait été de ne pas avoir à boucler sur tous les clients ou tous les fd pour savoir si ya ou non un event.

    J'aimerai avoir votre avis là dessus.
    Merci à tous.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Avec des contraintes pareilles, en environnement Microsoft, il faut se tourner vers les socket avec IoCompletionPort.

    Pour les autres OS, je ne sais pas.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Points : 41
    Points
    41
    Par défaut
    Salut !

    Merci pour la réponse .

    En effet là ça va tourner sur des serveurs linux. Apres reflexion (le fait d'avoir ecrit le post m'a aidé), je pense qu'au niveau perf de toute façon j'aurai pas mieux en faisant comme j'ai decrit.

    Le soucis des 500 µsec de latence n'est pas super grave. C'est surtout pour l'echange entre process via le socket INET_UNIX qui prend un peu plus de temps du coup. Le seul moyen de l'eviter c'est d'avoir un autre thread avec des poll sur des socket bloquants. Mais dans ce cas je devrai forcement me taper la gestion de mémoire partagée avec mutex ou semaphore. Et au niveau perf finalement j'y perdrai en gérant plus de choses.

  4. #4
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    Sans avoir tester l'appli dans un environnement chargé, je pense que :
    - sleep(500us) doit dormir bcp plus que ça je pense (ou alors redonne pas la main au scheduler et ce n'est pas très utile donc)
    - ce qui est cher, ce n'est pas tellement de parcourir les 2000 clients, mais de faire 2000 systèm call. Il serait bien plus efficace d'utiliser select ou epoll pour récupérer le status de ses 2000 clients et ensuite ne faire que les recv nécessaires). Je ne sais pas si epoll scale bien pour autant de fd.

    Après c'est difficile à dire sans profiler / tester en situation

  5. #5
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    je suis d'accord, remplacer le sleep par un select ou eventuellemt un poll (a voir en fonction de ton cas ce qui est le mieux) pour voir si quelque chose arrive sur tes socket me parait plus efficace.

    Surtout qu'il gère un time-out donc l'equivalent d'un sleep s'il ne se passe rien.

    quelques exemple d'utilisation qui te permettron de voire comment ça marche.
    http://www.lowtek.com/sockets/select.html
    http://support.sas.com/documentation...lr2/select.htm
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Points : 41
    Points
    41
    Par défaut
    Salut !

    Merci de vos réponses.

    Oui j'ai déja travaillé avec des select et des poll. En fait le select m'avait géné à cause de sa limite de fd possible (genre 1000 pas plus). J'ai en prod un autre jeu qui accepte en pointe plus de 2000 client et les gere avec poll ça marche tres bien.


    Pour info, le usleep de 100µsec semble etre relativement precis, j'ai pas testé en dessous.

    Vous avez raison, je vais modifier mon programme maitre et faire un add/remove fds. Ma lib qui gere les socket poura lui demander d'ajouter/retirer les fd à ecouter. La boucle stopera avec le time out du poll que je pourai fixer à une valeur plus grande ou sera directement passante si ya qq chose à gerer au niveau des socket. Deriere je ne change rien au programme, je continu à parcourir tous mes clients pour faire les recv/send. Finalement j'ai même pas besoin de tester le revent puisque cela revient à boucler sur tous les clients.

    Cela dit j'imagine qu'il doit etre plus rapide de tester un revent sur chaque client (enfin la structure du poll fd associé au client) que d'appeller un recv et voir si ya quelque chose dedans non ?

    En tout cas merci à vous

  7. #7
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Quelque soit la méthode que tu utilise tu sera confronté a des limites.

    Sous linux ce type de limites sont gérée par la command ulimit.

    Exemple pour connaitre les limites sur un compte utilisateur quelquonque:
    $ulimit -a
    core file size (blocks, -c) unlimited
    data seg size (kbytes, -d) unlimited
    file size (blocks, -f) unlimited
    open files (-n) 256
    pipe size (512 bytes, -p) 8
    stack size (kbytes, -s) 2042
    cpu time (seconds, -t) unlimited
    max user processes (-u) 63
    virtual memory (kbytes, -v) 2097152
    Ici un process ne sera pas capable d'ouvrir plus de 256 fichiers simultanément, note unix/linux considère une socket comme un fichier de ce point de vue.

    Cette limite peux être augmenté/réduite par un administrateur - ou un utilisateur ayant certains droits - en fonction des besoins de ton application. Cependant tu aura toujours une limite max imposé par le hardware/OS qu'un processus ne pourra pas dépasser.

    Ici je n'ai pas le droit de modifier le nombre de fichier que j'ouvre simultanément (root le pourrait), par contre je peux modifier celles des core dump eventuellement générée par mes processus.

    $ulimit -n 128
    bash: ulimit: file size: cannot modify limit: Invalid argument
    $ulimit -c 1024
    $ ulimit -a
    core file size (blocks, -c) 1024
    data seg size (kbytes, -d) unlimited
    file size (blocks, -f) unlimited
    open files (-n) 256
    pipe size (512 bytes, -p) 8
    stack size (kbytes, -s) 2042
    cpu time (seconds, -t) unlimited
    max user processes (-u) 63
    virtual memory (kbytes, -v) 2097152
    Bref, quelque soit tes choix de design/technique, ton OS t'imposera des limites que tu devra prendre en compte.

    Il existe aussi des façon de contourner un peu certaines de ces limites par Exemple si un processus ne peut pas ouvir plus de 1024 fichiers, deux processus ne pourront pas en ouvrir plus de 2048. donc avec undesign multi-processus on peut ouvrir plus de fichier.




    Quelques liens utiles pour jouer avec les limites.
    http://linux.die.net/man/2/setrlimit
    http://linux.die.net/man/2/getrlimit
    http://linux.die.net/man/3/sysconf
    http://linux.die.net/man/7/capabilities
    http://ss64.com/bash/ulimit.html
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Points : 41
    Points
    41
    Par défaut
    Salut !

    Oui je travaille sur des serveurs dediés HG d'OVH depuis pas mal de temps. Les ulimit sont définis comme les conn_track et le nombre maxi de port utilisable.

    Il est prevu que le process se connecte à d'autre process vi INET_UNIX. L'idee c'est de bien pouvoir utliser les 24 coeurs du serveur sans avoir à gerer la mémoire partagée. Il est d'ailleurs prevu que certains process se comportent comme des nodes et se connectent via TCP à d'autres machines sur lesquelles tourneront aussi jusq'a 24 process. Ainsi on peut monter en nombre de serveur au fur et a mesure que la charge monte.

    Les clients se connecteront à l'un ou l'autre des process en fonction d'un simple modulo de leur id en bdd. Chaque process saura gerer un client pour lequel il est prevu qu'il s'y connecte.


  9. #9
    Membre actif
    Profil pro
    Directeur technique
    Inscrit en
    Juillet 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 107
    Points : 200
    Points
    200
    Par défaut
    Je te conseillerai de jeter un oeil a Kqueue, qui, a ma connaissance est la methode qui supporte mieux la charge ( beaucoup mieux que select, mieux que pool / epool )

    http://www.daemonforums.org/showthread.php?t=2124

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Points : 41
    Points
    41
    Par défaut
    MErci

    Je vais regarder ça ^^

Discussions similaires

  1. [AC-2010] Votre avis sur deux schémas (Gestion de révisions, de documentations etc)
    Par Doutrick dans le forum Modélisation
    Réponses: 3
    Dernier message: 30/09/2014, 11h56
  2. Votre avis sur fichier Excel-Vba gestion des stocks
    Par mira3 dans le forum Conception
    Réponses: 5
    Dernier message: 10/04/2012, 10h01
  3. [MCD] Votre avis ma gestion basique de menu web
    Par arthuro45 dans le forum Schéma
    Réponses: 6
    Dernier message: 25/11/2010, 15h16
  4. votre avis (inter process)
    Par giova_fr dans le forum C#
    Réponses: 9
    Dernier message: 30/01/2008, 10h48
  5. Votre avis sur les outils de gestion qualité du codage
    Par leminipouce dans le forum Qualimétrie
    Réponses: 1
    Dernier message: 19/10/2006, 21h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo