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

Réseau C Discussion :

conception serveur multithread


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Par défaut conception serveur multithread
    Bonjour,

    Je sais qu il y a eu pas mal de topic dessus. Mais je donner les information sur mon implementation et avoir vos opinions.

    J ai un server qui est connecte sur un seul port, et j aimerai qu il dialogue avec plusieurs clients.

    Au depart je penser creer un thread pour chaque client et ensuite le detruire. Mais cela risque d etre couteux a chaque fois de creer un thread et de le detruire surtout si le nombre de client est grand.

    J ai donc opte pour le la creation de X threads, et si ces X threads sont tous occupe, alors on attend la terminaison de l un.

    Pour gerer cela, je creer une file qui sera rempli par la main et les thread (de maniere exclusive) prendrons un element de la pile.


    Pour la reception des messages :
    ca serai le main qui s occuperait de receptionner le message et lancerai un thread pour avec les donnees a traiter.

    Pour l envoie des messages :
    Je pense que la meilleure chose a faire et que se soit les thread qui envoie les message aux clients.

    Evidement je devrais utiliser un mutex pour pouvoir lire et ecrire.
    Mais une chose me tracasse, j ai peur le le main recois trop de message et ne laisse pas assez le tps au thread d envoyer les donnees. Dans ce cas la taille du buffer de la socket risque d etre depassee. Pour cela il suffirait peut etre de faire un sleep de 1 seconde (apres que le main ait relache le mutex) pour laisser au thread le temps d envoyer les donner). Mais j ai peur aussi de faire un sleep trop long ce qui exposera la taille du buffer de la socket.
    D ailleurs la taille maximum du buffer d une socket est de combien ?

    Ensuite je dois gerer le cas des sockets bloquantes. pour cela j utilise la fonction select(), ce qui me permettra de gerer les time out (je ne vois que ca pour son utilisation, si y en a dautre n hesitez pas a me le dire).

    voila comment je compte faire.

    Merci de me faire parvenir vos opinions.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    salut,

    tu te compliques un peu la vie, car le systeme peut gerer beaucoup de choses pour toi, mais tu as raison concernant le "pool" de threads (par opposition a creer un thread a chaque connexion).

    la plupart des serveurs TCP necessitant un temps de latence minimal a la connexion utilisent cette methode; il s'agit du modele "pre-fork" (mis en oeuvre, entre autres, par Apache).

    le principe consiste a creer un certain nombre (configurable) de processus fils en prevision de variations subites du nombre de clients (et donc de connexions); cette technique peut egalement s'adapter aux threads, voire a une combinaison de processus et de threads.

    c'est la que le systeme intervient de facon interessante: lorsque tu crees un socket, et que tu le met en ecoute sur un port, plusieurs threads peuvent simultanement faire un accept() sur ce meme socket. quand une connexion intervient, l'OS l'attribue a un des threads en attente, et le fait sortir du accept(); les autres threads restent en wait.

    je te propose un petit exemple ici.

    il s'agit d'un serveur "echo" (il renvoie a chaque client tout ce qu'il recoit de chacun d'eux). compile-le et lance le avec:

    par defaut, 32 threads sont crees (il peut etre interessant d'en modifier le nombre afin d'observer le comportement du serveur en cas de nombreuses connexions). tu peux verifier que tout fonctionne correctement en lancant par exemple la commande suivante depuis plusieurs terminaux differents (elle envoie de facon repetitive le contenu du binaire "/bin/ls" au serveur, et fait un checksum de la reponse):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while true; do nc -q 1 127.0.0.1 1234 < /bin/ls | md5sum; done
    le md5sum te permet de controler de facon empirique que chaque thread gere correctement son contexte.

    il faut cependant garder a l'esprit que chaque processus a des resources limitees (nombre de sockets ouverts, en particulier). ici, tous les threads (tcpthread) font partie du meme processus.. si tu as besoin de gerer simultanement un nombre tres important de connexions, il faut envisager de creer plusieurs processus fils, puis plusieurs threads par processus.

    -pirus.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Par défaut
    ok, mais ds le programe , les thread font des read et des write sur la sockets sans tenir compte d aucun mutex ....

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    Citation Envoyé par nivose110
    ok, mais ds le programe , les thread font des read et des write sur la sockets sans tenir compte d aucun mutex ....
    il n'est pas necessaire de placer de mutex ici; chaque thread obtient son propre socket (le retour de accept() est un nouveau socket).

    en d'autres termes, les mutex sont necessaires lorsque plusieurs threads sont susceptibles de manipuler une meme resource au meme moment, ce n'est pas le cas ici.

    la seule resource partagee entre les threads est la structure tCtx. le controle de l'acces a ses elements (en particulier ctx_count) se fait via un mutex (et une "condition variable").

    -pirus.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Par défaut
    hummmm ok. Cette methode m a l air vraiment pas mal !!!

    Mais une derniere chose me gene .

    Alors imaginons que l on a X thread. Imaginons que les X threads sont pris (par donc X clients), Un X+1 eme client se connect, il devra attendre que l un des thread est fini avec un client. Un fois que tun thread ait fini, il lui reste plus qu a refaire un accept c ca pour accepter la connection du client X+1 ? (evidemment le thread aura dermer la socket), car dans le programme donne, le thread une fois qu il a traite un client, il se ferme.
    De plus ne serait il pas mieux de creer les thread suivant le nombre de clients aulieu de creer X thread et X-n seront endormis en attente de nouveau clients ?

    Genre le main genre gere les accepts et cree un thread avec en parametre la socket.

  6. #6
    Membre éprouvé
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Par défaut
    Citation Envoyé par nivose110
    De plus ne serait il pas mieux de creer les thread suivant le nombre de clients aulieu de creer X thread et X-n seront endormis en attente de nouveau clients ?

    Genre le main genre gere les accepts et cree un thread avec en parametre la socket.
    creer // detruire des threads est couteux en ressource, si 10 clients se connectent simultanement, tu met ton server sur les genoux.

    pour un server qui gere moins d'une centaine de clients (ca depend de l'application aussi), une solution avec select marche TRES bien.

    tu utilise un thread qui fait tourner ton select et utilise une pipe (ou des tableaux de char pour rester portable) et des mutex.
    tu reçois un truc, tu debloque un mutex, le main fait le traitement et rempli un autre tableau de char puis debloque un mutex sur lequel attendais ton thread 'gestion client' (avec le select) et envoi ton message.
    bien sur cette methode n'est pas tres efficace si le traitement et/ou le nombre de clients est important.
    je pense que pour pouvoir te conseiller correctement il faudrais que l'on ait plus de precisions sur la fonction de ton server.
    de plus, il y'as de tres bon specialistes reseaux dans le forum consacré aux reseaux ...

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 86
    Par défaut
    desole pour la reponse un peu tardive, j'etais sur la route..

    effectivement, une fois qu'un thread se termine, il ferme son socket, mais il ne s'agit pas du socket en listen (auquel on ne touche jamais, il reste toujours ouvert par le thread principal), il s'agit d'un socket connecte (donc associe a un client)

    essaye avec X = 2 par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ./tcpserver 1234 2
    puis lance 3 telnet depuis 3 terminaux differents, et regarde si le comportement du serveur correspond a ce que tu attends.

    pour ce qui est de la gestion dynamique du nombre de threads, tu as raison, ca peut etre interessant. je ne l'ai pas fait pour deux raisons:

    • le but etait de presenter un exemple simple de synchronisation autour de accept(), un nombre arbitraire de threads s'y pretait tres bien (sans alourdir inutilement le code),
    • il aurait fallu choisir (arbitrairement aussi) une politique de creation/suppression des threads, selon moi, ce choix doit etre fait en fonction de l'application.


    cependant, tu peux modifier la variable nthr afin de faire varier dynamiquement le nombre de threads. il n'y a rien d'autre a faire (pas de table a redimensionner, etc..). de plus, la methode qui consiste a utiliser une combinaison de threads "detached" et une "condition variable" pour la notification du thread principal apporte beaucoup plus de souplesse qu'un pthread_join().

    tu dois assez facilement pouvoir en faire ce que tu veux, a partir du moment ou tu as decide d'une politique d'allocation de threads. puis bon, c'est juste un exemple.. meme si je me plais a penser qu'il-y-a des choses interessantes a y piocher, je ne pretends pas que ce soit forcement la solution qui te convient le mieux.

    -pirus.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Arrêt d'un serveur multithread
    Par bambou dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 07/07/2010, 16h04
  2. Question Serveur Multithread
    Par Mr_Chut dans le forum Réseau
    Réponses: 10
    Dernier message: 09/06/2006, 17h27
  3. [Conception] Serveur distant
    Par keil dans le forum Général Java
    Réponses: 8
    Dernier message: 26/02/2006, 09h27
  4. Réponses: 5
    Dernier message: 11/01/2006, 07h58

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