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 :

Un socket est-il "bidirectionnel" en parallèle ?


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Points : 21
    Points
    21
    Par défaut Un socket est-il "bidirectionnel" en parallèle ?
    Bonjour à tous,

    pour conclure normalement mon projet informatique une question reste en suspens.

    J'ai un socket partagé entre deux threads : un qui envoi et un autre qui réceptionne des messages (logique).

    La question existentielle que je me demande à l'heure de finaliser par des protections mutex c'est est-ce qu'il faut aussi protéger send et receive ???

    Le socket est utilisé mais il n'est, me semble-t-il, pas modifier... or si je suis obligé d'instaurer un système de mutex cela veut dire que je ne peux pas envoyer quand je reçois... ni recevoir quand j'envoie.... C'est très embêtant ça ! Autant ne pas envoyer quand je reçois un message je veux bien... mais ne pas recevoir quand je reçois c'est plus qu'embêtant.

    Donc si je devais résumer mon problème en une question :

    Peut on émettre et recevoir sur un même socket en même temps sur deux threads parallèles sans aucun problème.

    Si non... je ne vois pas du tout comment ne pas éviter une perte importante de messages reçus.

    Merci beaucoup

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 124
    Points : 148
    Points
    148
    Par défaut
    Pas besoin de lock pour send et recv, ton système fonctionne.

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Points : 21
    Points
    21
    Par défaut
    Tu sauves la vie de mon projet Merci mille fois !

    Dernière petite question et je finalise ça : a-t-on besoin de protéger l'accès à une variable seulement si on la lit ? Je me disais que ce n'était que dans le cas d'une modification qu'il était dangereux d'y aller à deux dessus (la pauvre).

    genre while(!(queue.isempty())) j'ai besoin de le protéger ça ?

    alors qu'un queue.pop(); j'imagine bien que oui !

    Pour ma part je dirais oui car sinon le socket serait justement obligé de recevoir du mutex.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 124
    Points : 148
    Points
    148
    Par défaut
    Est a protéger, si l'autre thread a déjà pris le dernière objet et qu'il pop juste après ton test empty tu vas récupérer une exception.
    Mais généralement on essaye de ne pas utiliser le même conteneur pour tout les threads, on découpe la queue en plusieurs queue plus petite pour ne pas avoir justement a gérer les zone critique.
    PS : On dit qu'un socket est full-duplex non pas bidirectionnel.

  5. #5
    Membre à l'essai
    Inscrit en
    Juin 2009
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 49
    Points : 21
    Points
    21
    Par défaut
    Tout à fait ça c'est évident, mais là justement c'est le thread concerné qui pop... donc aucun risque qu'il dépop alors que c'est vide !

  6. #6
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par thebop Voir le message
    Si non... je ne vois pas du tout comment ne pas éviter une perte importante de messages reçus.
    Parcequ'il y a un "buffer" ?

    Le buffer de reception n'est pas très gros par défaut je crois, mais est modifiable avec setsockopt(SO_RCVBUF)
    Tant que tu es en dessous de ce buffer, no problem, tu ne perdras rien...
    Au delà du buffer...
    En TCP, les paquets de données seront renvoyées automatiquement par le client (transparent à TCP).
    En UDP, ben.... osef ! Vu que tout client UDP doit s'attendre à la perte de paquets.

    Perso, je prefere garder mes sockets dans un seul thread, juste histoire d'être sur de ne pas avoir de problême de select()/wait(). Mais c'est un avis personnel.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  7. #7
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par thebop Voir le message
    mais ne pas recevoir quand je reçois c'est plus qu'embêtant.
    Ce n'est en général qu'une impression : le médium final est habituellement sériel, c'est à dire que tu n'émets pas en même temps que tu reçois (CSMA/CD).
    On peut passer outre et avoir du full-duplex "réel" (c'est à dire sur le médium physique, ce qui implique en fait d'avoir deux "lignes" ou plus sur le câble réseau), mais sans savoir comment est fait ton réseau local, vaut mieux partir du principe que tu es bel et bien sérialisé. Donc, deux threads pour gérer ça est (habituellement) inutile.


    Sinon, j'ai tendance à préférer un seul thread par socket, gérant la "pompe à trames", couplé à deux FIFO utilisateur (une pour la réception, une pour l'émission). En fabriquant ton thread, tu décides donc de la taille des buffers, de la priorité du thread lui-même, et bien sûr de l'ordre de préséance entre l'émission et la réception.

    Ensuite, tu colles des threads sur ces FIFO si besoin, mais derrière ta socket vit sa vie toute seule, gérée par son thread, et toi tu n'as plus qu'à taper dans des FIFO sans te préoccuper du reste. Tu as en plus l'avantage d'être plus indépendant du système d'exploitation, et tu t'adaptes à n'importe quel OS juste en touchant le thread de gestion des sockets, et non pas le reste de l'application.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

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