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

Threads & Processus C++ Discussion :

Précision sur fonction static d'une classe pour Thread


Sujet :

Threads & Processus 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 Précision sur fonction static d'une classe pour Thread
    Voilà j'ai codé une classe composée d'un socket en attribut.

    Je dois créer un thread dans le main qui reçoit en parallèle des informations sur le socket.
    Le problème est que pour créer ce thread je dois passer ma méthode rcv() en static void... Mais qui dit static dit perte des attributs de l'instance de classe !

    J'ai donc une question : Quelle est la meilleure stratégie à employer pour pouvoir utiliser mes attributs au sein de ma classe et être sûr qu'ils seront bien modifiés en parallèle dans l'objet instancé dans mon main ?

    Passer mon objet en référence ? Ce dont j'ai peur c'est que ce thread modifie un tableau dynamique attribut de mon objet... Est-ce que pour autant si je regarde l'état du tableau dans le main il aura bien été modifié en temps réel par le thread ?

    Exemple en pseudo code pour pas piquer les yeux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    class objet{
    private :
    std::vector bidon
     
    public:
    void setvector(int);
    std::vector getvector();
    static void rcv(objet) //Thread qui reçoit constamment des informations en parallèle
    }
     
    int main()
    {
       objet obj;
       obj.setvector(5);
     
       thread(obj.rcv(&obj)); //Modifie le vector au bout de 1 seconde en ajoutant 3
     
       sleep(2);
       obj.setvecor(8);
     
       cout << obj; //5 3 8 ?
     
    return 1;
    }
    Merci beaucoup !

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    Citation Envoyé par thebop Voir le message
    Le problème est que pour créer ce thread je dois passer ma méthode rcv() en static void... Mais qui dit static dit perte des attributs de l'instance de classe !

    J'ai donc une question : Quelle est la meilleure stratégie à employer pour pouvoir utiliser mes attributs au sein de ma classe et être sûr qu'ils seront bien modifiés en parallèle dans l'objet instancé dans mon main ?
    La meilleur, je ne sais pas. Une solution souvent mise en oeuvre consiste à passer un pointeur sur l'objet en tant que paramètre de ta méthode statique. Cette dernière se contente ensuite d'appeler une méthode non statique sur l'objet passer en paramètre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void A:static_callback(void *pv_param)
    {
       return reinterpret_cast<A*>(pv)->Methode();
    }
    Citation Envoyé par thebop Voir le message
    Ce dont j'ai peur c'est que ce thread modifie un tableau dynamique attribut de mon objet... Est-ce que pour autant si je regarde l'état du tableau dans le main il aura bien été modifié en temps réel par le thread ?
    Je ne comprends pas trop quelle question tu te poses exactement.
    Si tu partages un objet entre plusieurs thread, alors tu dois mettre en oeuvre un mécanisme de contrôle d'accès (mutex) pour fiabiliser ce partage.

  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
    Ok oui j'ai une question à ce propos sur les mutex... Est-ce que les mutex n'ont une utilité qu'entre thread ? Parce que je ne vois pas très bien l'utilité de mettre des mutex dans le main avec le principe de mémoire partagée.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonsoir,
    Les mutex permettend un accès mutuellement exclusif aux différentes ressources que peuvent partager des threads : le thread principal et les threads secondaires. Ca évite par exemple, d'essayer de modifier une même variable en même temps, sans quoi le résultat est indéterminé... Le problème de la mémoire partagée est identique : il te faut savoir quand tu peux lire ou écrire dans la mémoire partagée de façon à ce qu'aucun n'autre thread ne le fasse en même temps.
    Sous windows, les mutex peuvent être nommés et permettrent la synchronisation d'accès à des ressources partagées entre des processus.

  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
    Ok Ok je vais y réfléchir, pas simple cette affaire pour un premier projet...

    Merci beaucoup

  6. #6
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void A:static_callback(void *pv_param)
    {
       return reinterpret_cast<A*>(pv)->Methode();
    }
    Hum par contre je ne comprends pas trop en fait le fonctionnement de reinterpret_cast surtout ce que je ne comprends pas c'est qu'on renvoit une méthode... Je pensais qu'à l'origine static_callback permettait de réinterpréter en tout début du thread mon void* en un pointeur sur mon objet mais là j'ai du mal à saisir comment elle doit être appelée et que veut dire (pv)-> Methode...

    Il ne vaut mieux pas faire tout simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a = reinterpret_cast<A*>(a); // ?
    Parce que dans mon thread là je fais directement un reinterpret_cast mais le compilateur ne veut toujours pas comprendre quand je fais appel à des méthodes de l'objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void* Mobile::sendu(void* mob)
    {
        mob = reinterpret_cast<Mobile*>(mob);
        string buffer;

  7. #7
    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
    La seule façon que j'arrive pour compiler c'est de créer un objet temporaire en début de thread :

    Mobile* mobt = reinterpret_cast<Mobile*>(mob);

    Mais du coup les threads ne vont pas partager le même objet !! (enfin je crois...)

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par thebop Voir le message
    La seule façon que j'arrive pour compiler c'est de créer un objet temporaire en début de thread :

    Mobile* mobt = reinterpret_cast<Mobile*>(mob);
    ceci ne crée pas un objet temporaire mais récupère l'adresse dans mobt. L'objet pointé est le même que celui fourni en paramètre à l'appel.
    Citation Envoyé par thebop Voir le message
    Mais du coup les threads ne vont pas partager le même objet !! (enfin je crois...)
    Les adresses étant les mêmes, ce sont les mêmes objets.

  9. #9
    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
    Ok j'avais testé, ça semble marcher.

    J'ai une dernière question, j'ai un thread qui envoi sur un socket et l'autre qui reçoit.... évidemment c'est le même socket... J'imagine que ça pose un problème et que je dois implanter des mutex par-ci par-là.

    Mais alors c'est embêtant ça parce que si j'envoie je ne peux pas recevoir... et donc je perds éventuellement un message que je pourrais avoir reçu pendant mon temps d'émission.
    Il faudrait mettre un système de priorité à receive() pour que dès qu'il y ait un message reçu c'est lui qui ait la priorité immédiate sur send()... mais là je ne vois pas du tout comment faire ça avec du mutex.

    Ou alors on peut émettre et recevoir sur le même socket car de toute façon on ne le modifie pas lors de ces deux actions, et le problème ne se pose donc plus.

    Merci.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par thebop Voir le message
    Ok j'avais testé, ça semble marcher.

    J'ai une dernière question, j'ai un thread qui envoi sur un socket et l'autre qui reçoit.... évidemment c'est le même socket... J'imagine que ça pose un problème et que je dois implanter des mutex par-ci par-là.
    Si les échanges concernent 2 threads de la même application, l'échange par socket ne me semble pas le plus pertinent.
    Ceci dit, je ne sais pas exactement jusqu'à quel niveau tu dois sécuriser l'accès à ta socket dans un tel mutex. A priori, je dirais que tu dois utiliser ton mutex pour gérer chaque appel (recv/send, mais aussi les autres). Pour les appels bloquant, je ne pense pas qu'il y ait de problème. En revanche, pour les appels non bloquants, j'avoue que je sais pas si en interne les accès sont protégés contre la concurrence.

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/01/2015, 17h36
  2. Réponses: 5
    Dernier message: 18/11/2007, 01h15
  3. Réponses: 2
    Dernier message: 22/12/2006, 11h35
  4. fonction static dans une class
    Par Stany dans le forum C++
    Réponses: 3
    Dernier message: 16/06/2006, 14h43
  5. Pointeur sur des fonctions membres d'une classe
    Par Muetdhiver dans le forum C++
    Réponses: 3
    Dernier message: 15/02/2006, 11h35

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