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

Windows Discussion :

un ou plusieurs threads?


Sujet :

Windows

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut un ou plusieurs threads?
    Je souhaite créé un serveur qui pourrait biensur accepter plusieurs clients, je me demande si il est préférable de créé un thread par client, ou bien de créé un thread qui s'occupe de la communication avec tout les clients? je pensais aussi utiliser WSAEventSelect() et récupéré les evenements winsock comme ca.

    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Cela dépend de la durée des requètes. Si elles sont rapides à traiter (un t'chat par exemple), tu peux faire un seul thread pour tous les clients, je l'ai déjà fait.

    (mais moi, j'utilisais WSAAsyncSelect(), par contre.
    Celui-ci ne s'utilise plus comme select() contrairement à WSAWaitForMultipleEvents(), mais s'utilise au contraîre avec une fenêtre)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    théoriquement, il est possible de faire un serveur en mode non-blockant dans qui n'affiche qu'une fenetre console(comme dos), est t'il préférable de faire une fenetre windows?
    Si jamais je fais une fenetre win32 avec des composants textbox, boutons, et list, qu'elle sont les apis à utiliser (pour la création et l'utilisation)? et comment gerer ces composants et modifier leurs propriétés.

  4. #4
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    en faite, je vien de voir que je peux créé mes controles, avec createwindow, alors juste une dernière question, il est préférable de créé les composants comme ca ou bien de faire une dialbox (en ressource)?

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Pour te dire, j'ai fait les deux (fenêtre et BDD) et pour ce qui est du réseau, je n'ai pas vraiment vu de différence.

    Simplement, avec une boite de dialogue, tu n'as pas besoin de gérer toi-même la police des contrpoles.
    Et si elle est modale (cad exécutée avec DialogBox et non pas CreateDialog+boucle de messages), le passage d'un contrôle à l'autre (tabulations etc.) est géré automatiquement.

    L'inconvénient, c'est qu'avec une boite de dialogue modale, on ne peut pas intercepter facilement la touche ESC. (Elle fait toujours ANNULER. Enfin, on peut toujours ne rien faire avec le bouton ANNULER, mais dans ce cas, on ne peut plus fermer en cliquand sur la croix)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2005
    Messages : 177
    Par défaut
    Pour le premiere question ^^.
    Je dirais dans tout les cas des threads ^^. Pourquoi ?

    1 - Pour éviter les crashs généraliser (Si un thread plante ca ne deconnecte que 1 client)
    2 - C'est une maniere de gérer le "multi-client asynchrone" efficacement.
    3 - Tu bénéficie directement de tout les avantage apporter par les thread. (priorité en cas d'administration distante/ pause etc ...)

    Si ce sont des petites ou longues opérations, mais qui doivent etre avec un temps de réponse très rapide (des flux de connections). Il est très avantageux de faire des pool de thread. C'est a dire que tu précrée les thread qui attendrons sur un mutex leur tache ^^.


    2eme question, La fenetre ^^
    Ici c'est plus un poin de vu de conception qu'il faut prendre en compte. Ton serveur, si ca devient un véritable server tournera en services(windows) ou en deamon(linux/unix/bsd). Il t'est alors impossible de crée une fenetre. Par cotre il est bien venu de loggué dans des fichier. C'est la qu'arrive l'enorme avantage des flux, tu remplace vite "cout" par un autre flux ^^.
    De plus pour le Winsock Fait attention avec les MFC. Je pense qu'il y a certain incompatibilitèe car il ajoute une version antérieur.
    MSDN :
    MFC supports Windows Sockets 1 but does not support Windows Sockets 2. Windows Sockets 2 first shipped with Windows 98 and is the version included with Windows 2000.

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par Heptaeon
    1 - Pour éviter les crashs généraliser (Si un thread plante ca ne deconnecte que 1 client)
    Si un thread part en boucle infinie ou deadlock oui, mais un plantage tue tout le processus, donc aucune différence de ce coté-là.

    Si ce sont des petites ou longues opérations, mais qui doivent etre avec un temps de réponse très rapide (des flux de connections). Il est très avantageux de faire des pool de thread. C'est a dire que tu précrée les thread qui attendrons sur un mutex leur tache ^^.
    Les pools de threads peuvent être indépendants de ce que fait le serveur : on n'est pas obligé d'avoir en permanence un thread par client dans ce cas. Avec un seul thread, il y aura moins de problèmes de synchonisation/table de clients connectés s'il y a/etc.

    2eme question, La fenetre ^^
    Ici c'est plus un poin de vu de conception qu'il faut prendre en compte. Ton serveur, si ca devient un véritable server tournera en services(windows) ou en deamon(linux/unix/bsd). Il t'est alors impossible de crée une fenetre.
    Je crois bien qu'en services, on peut avoir une fenêtre, mais pas sur le bureau visible...
    Ce pour quoi j'ai des doutes, c'est pour les NotifyIcons... (icônes en bas à droite de la barre des tâches, j'ignore si on peut s'en servir avec les services...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    J'ai décidé de faire sans fenêtre là. Je les crée quand et comment mes threads? Je pensais en créé un des que le programme est bien démarré, et mettre alors un socket en écoute, mais je met le socket en écoute avant de créé le thread ou apres? et le WSACreateEvent, je le fais quand?
    Si quelqu'un pouvait m'écrire un plan du code que je devrais faire, pour avoir une idée de l'ordre dans lequel les choses doivent se passer.

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Si tu utilise les WSAEVENTs, tu n'as pas besoin de multi-thread non plus.
    C'est comme programmer avec select(), ce qui permet de faire des serveurs entièrement monothreadés (simplement, ils attendent sur WSAWaitForMultipleEvents() au lieu de select(), tandis que les serveurs avec WSAAsyncSelect() bouclent sur le GetMessage())

    Le WSACreateEvent, tu peux en créer un pour le socket d'attente, (WSAEventSelect() avec FD_ACCEPT) puis tu en crées un pour chaque nouveau client, juste après le accept() (WSACreateEvent(), WSAEventSelect() , avec FD_READ, et FD_CLOSE sur le socket retourné par le accept())

    Ainsi, après le WSAWaitForMultipleEvents(), tu sauras que l'un des sockets vient de recevoir des données ou d'être fermé, (ou qu'un nouveau client est en train de se connecter sur le socket d'attente) et tu pourras agir en conséquence. (utilise WSAEnumNetworkEvents() sur l'événement signalé pour savoir ce qui s'est passé sur le socket en question)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    Je pensais utilisé le thread main pour lancer le prog, puis attendre qu'on tape des commandes dans la console, c'est pourquoi j'aurais fait un thread qui gere juste le réseau (évidement je lance le traite avant d'attendre les messages de la console). C'est une bonne idée? si oui, la ou les fonctions pour faire un thread?

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    tu peux très bien faire un thread console et un thread réseau.
    Tu peux même t'assurer que le thread réseau quitte correctement sans le tuer, avec une variable globale déclarée volatile, car les fonction select() ou WSAWaitForMultipleEvents() ont un timeout.

    La fonction Windows pour créer un nouveau thread, c'est CreateThread(). Ne soit pas effayé par les paramètres, la plupart ont des valeurs par défaut.
    Le Handle retourné peut être utilisé pour attendre la fin effective du thread après lui avoir demandé de se terminer, par exemple (fonction WaitForSingleObject())

    Et quand tu n'as plus besoin du handle du thread, tu t'en débarasses avec CloseHandle(). (cela ne tue pas le thread).


    Si tu veux faire du portable, tu peux utiliser les threads POSIX à la place, ils ont leurs propres fonctions...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    Tu peux même t'assurer que le thread réseau quitte correctement sans le tuer, avec une variable globale déclarée volatile, car les fonction select() ou WSAWaitForMultipleEvents() ont un timeout.
    je vois pas trop ce que ca veut dire tout ca. Quelques détails?

    Et pour le timeout, j pensais mettre illimité, j pense que c'est possible.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Je veux dire que si tu veux qu'un thread dise à l'autre de se terminer proprement, il faut le moyen de le signaler.

    Cela peut se faire par des outils de synchronisation (malheureusement incompatibles avec Select() et WSAWaitForMultipleEvents()) ou une vagiable globale modifiée, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    volatile bool g_bQuitThread;
    qui passe à true quand on veut que le thread se termine.

    Mais pour cela, il faut vérifier régulièrement que ladite variable a changé, et c'est là que les timeouts prennent tout leur intéret: plutôt que d'attendre indéfiniement qu'il se passe quelque chose sans jamais consulter la variable, on la vérifie tous les X (2 secondes par exemple, il suffit de régler le timeout à 2000ms et de vérifier la variable entre chaque appel à la fonction d'attente: si celle-ci indique que le thread doit se terminer, on sort de la boucle).

    Ainsi, dans le thread principal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    g_bQuitThread = true;
    WaitForSingleObject(hThread, INFINITE);//on lui dit d'attendre indéfiniement, 
    //mais le thread attendu devrait se terminer au bout de 2 secondes max
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    apres avoir appeler la fonction Waitforevent, on utilise enumevent pour savoir si il y a bien un evenement ou on sait le savoir autrement? (histoire d'évité des opérations inutiles)

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    on n'utilise WSAEnumNetworkEvents() que si la fonction WSAWaitForMultipleEvents() a indiqué qu'il y avait un événement sur un socket client.
    Ceci parce que les sockets clients ont DEUX types d'événement possible, mais forcément sur le même WSAEVENT. (FD_READ ou FD_CLOSE)
    Alors, on appelle WSAEnumNetworkEvents() sur le WSAEVENT en question pour savoir lequel des deux types d'événement est arrivé (il est possible qu'il y ait les deux à la fois: tester avec | et non == )

    Par contre, si WSAWaitForMultipleEvents() renvoit "timed out" ou renvoit l'événement du socket d'attente, pas besoin d'appeler WSAEnumNetworkEvents() : S'il y a time out, c'est qu'aucun événement n'est arrivé, et s'il y a le socket d'attente, lui n'a qu'un seul type d'événement : FD_ACCEPT.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    C'est spécifique Windows, je déplace.
    Citation Envoyé par Heptaeon
    2 - C'est une maniere de gérer le "multi-client asynchrone" efficacement.
    je dirais simplement, mais efficacement, c'est à voir. Un thread n'est pas gratuit.
    Personnelement, je pense que le réel intérrêt des thread est en multi-processeur / hyperthreading. Sinon, vaut mieux éviter leur nombre. L'utilisation d'overlapped I/O est à priori le plus performant, mais c'est assez lourd à mettre en oeuvre. Les thread c'est plus simple. Si tu as un nombre assez faible de clients connectés simultanément, ça fera l'affaire, à mon avis. La solution à base de thread est aussi plus facilement portable.
    http://tangentsoft.net/wskfaq/articles/io-strategies.html

  17. #17
    Membre confirmé Avatar de greg13
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    144
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 144
    Par défaut
    merci beaucoup, c'est vraiment interressant ce lien. merci beaucoup.

Discussions similaires

  1. [Thread] Gestion de plusieurs thread
    Par be_tnt dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 14/07/2006, 13h35
  2. RS232: Un seul ou plusieurs threads?
    Par cfalcot dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 01/04/2006, 23h01
  3. plusieurs threads ecrivent sur la meme socket
    Par estergiou dans le forum C++
    Réponses: 3
    Dernier message: 04/11/2005, 01h38
  4. [Thread]Comment créer plusieurs thread à la demande??
    Par Devil666 dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 14/09/2005, 13h29
  5. création de plusieurs threads dans WinMain
    Par ChidoriRasengan dans le forum DirectX
    Réponses: 1
    Dernier message: 15/06/2005, 21h36

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