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 :

[Debutant] MultiThread et conseils de développement


Sujet :

C++

  1. #1
    Membre régulier
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Points : 122
    Points
    122
    Par défaut [Debutant] MultiThread et conseils de développement
    Bonjour,

    initialement j'executais ceci dans une classe main.cpp

    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
     
    //Connexion a un serveur OPC/DCOM
    CServerOPC toto(L"KepServer");
     
    //Création et ajout d'un groupe au serveur OPC
    CGroupOPC myOtherGroup(&toto,L"MyGroup");
     
    //Définition de la liste des Items
    CObArray listItem;
     
    //Création de l'item
    CItemOPC item(L"Canal.Device.Valeur",L"",&myOtherGroup);
     
    //Ajout de l'item à la liste d'item
    listItem.Add(&item);
     
    //Ajout des Items au groupe
    myOtherGroup.addItems(listItem);
     
    //Lecture des valeurs des items ajoutés
    myOtherGroup.ReadSyncIO(OPC_DS_DEVICE,listItem);
    La lecture ne s'effectuait qu'une seule fois.
    Voulant lire les valeurs cycliquement, toutes les secondes (pour le moment), j'ai crée (copié sur developpez.com) une classe Thread qui s'appelle CReaderThread.

    La fonction Execute permet d'executer dans le thread une liste d'instructions.

    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
    26
    27
    28
    29
    30
    UINT CReaderThread::Execute()
    {
        // exemple de code à exécuter
     
        DWORD start = ::GetTickCount();
     
    	CServerOPC toto(L"KepServer");
    	CObArray listItem;
    	CItemOPC item(L"Canal.Device.Valeur",L"",&myOtherGroup);
    	listItem.Add(&item);
    	myOtherGroup.addItems(listItem);
     
        do
        {   
            // code de traitement
    		cout<<endl<<GetTickCount(); 
     
                    //Lecture cyclique des threads
    		myOtherGroup.ReadSyncIO(OPC_DS_DEVICE,listItem);
     
            ::Sleep( 1000 ); // simuler une opération de 1 sec
        } while ( this->m_StopThread == false ) ;
     
        DWORD end = ::GetTickCount();
     
        // renvoyer un résultat : temps d'exécution
        this->ExecutionTime = end - start;
     
        return 0;
    }
    Là j'ai été obligé de rajouter dans cette fonction membre la liste d'instructions suivantes qui correspond à ma liste d'instruction obligatoires avant ma lecture
    CServerOPC toto(L"KepServer");
    CObArray listItem;
    CItemOPC item(L"Canal.Device.Valeur",L"",&myOtherGroup);
    listItem.Add(&item);
    myOtherGroup.addItems(listItem);
    et dans la boucle, j'ai mis la fonction de lecture.

    Pensez-vous que cette liste d'instructions devraient figurer dans le thread ou devrai-je la laisser dans main.cpp ?
    Si je la laisse dans main.cpp, je serai obligé de passer en paramètres les objets nécessaires à l'execution de ma fonction de lecture, chose que je ne trouve pas très propre et qui fait un peu bidouillé, qu'en pensez-vous ?

    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
    UINT CReaderThread::Execute(CGroupOPC group,CObArray listItem,DWORD opc_ds)
    {
        // exemple de code à exécuter
     
        DWORD start = ::GetTickCount();
     
        do
        {   
            // code de traitement
    		cout<<endl<<GetTickCount(); 
     
                    //Lecture cyclique des threads
    		group.ReadSyncIO(opc_ds,listItem);
     
            ::Sleep( 1000 ); // simuler une opération de 1 sec
        } while ( this->m_StopThread == false ) ;
     
        DWORD end = ::GetTickCount();
     
        // renvoyer un résultat : temps d'exécution
        this->ExecutionTime = end - start;
     
        return 0;
    }
    Ou alors devrai-je modifier la fonction de lecture de ma classe CGroupOPC pour qu'elle soit executé dans un thread ?

    Chose important aussi, j'aimerai par la suite dans le cas où l'appli n'est pas connecté au serveur OPC, qu'elle tente automatiquement et cycliquement de se reconnecter au serveur, d'où un nouveau thread.
    C pourquoi je pense aussi que l'instruction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CServerOPC toto(L"KepServer");
    ne pourrait pas se trouver dans le thread CReaderThread.

    En esperant avoir été claire.

    Merci d'avance pour vos réponses.
    ++

  2. #2
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Bonjour,
    Au vu de ta dernière remarque sur la connexion cyclique en cas de déconnexion, tu peux tout laisser dans le thread.

    Dans ce cas là, il te faut un Flag qui gère l'état de ton thread:
    Connecté, Déconnecté.

    Tu met le code dans la boucle du thread conditionné à ce flag:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    faire
        Si état est déconnecté alors 
                                       tenter une connexion
        effectuer les opérations cycliques (lecture...)
    Tant que le thread n'est pas terminé.
    Important: Si tu dispatches ta connexion sur plusieurs threads, il te faudra assurer par mutex ou section critique la synchronisation d'accès à la connexion.

  3. #3
    Membre régulier
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Points : 122
    Points
    122
    Par défaut
    Tu met le code dans la boucle du thread conditionné à ce flag:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    faire
        Si état est déconnecté alors
                                       tenter une connexion
        effectuer les opérations cycliques (lecture...)
    Tant que le thread n'est pas terminé.
    Dans le cas, où je suis déconnecté, alors je me reconnecte. Ca pourquoi pas.
    Dans le cas où je suis connecté, je dois absolument effectué (une seule fois) les instructions suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    CObArray listItem;
    CItemOPC item(L"Canal.Device.Valeur",L"",&myOtherGroup);
    listItem.Add(&item);
    myOtherGroup.addItems(listItem);
    Donc si je mets tout ça dans la boucle, je suis obligé de remettre un flag pour m'assurer que toute ces manip sont effectués. Cela ne va-t-il pas être un peu lourd ?

    Et sinon est-ce que la liste d'instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CServerOPC toto(L"KepServer");
    CObArray listItem;
    CItemOPC item(L"Canal.Device.Valeur",L"",&myOtherGroup);
    listItem.Add(&item);
    myOtherGroup.addItems(listItem);
    doit se trouver dans le thread ou en dehors, dans mon main par exemple?
    Parce qu'après tout le thread est juste pour la lecture, ne devrai-je pas mettre uniquement que l'instruction de lecture ?

    Merci d'avance.
    ++

  4. #4
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Toute mes excuses, j'ai rippé!

    Voici ce que je voulais dire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    faire 
        Si état est déconnecté alors debut
                                       tenter une connexion 
                                       {...} les instructions à faire une seule fois, lors de la connexion.
                                       Endormir le thread de Quantum millisecondes
    // Si on arrive ici, la connexion est établie.
    effectuer les opérations cycliques (lecture...) 
    Tant que le thread n'est pas terminé.
    CReaderThreadExecute n'a de sens (si j'ai bien saisi) que quand la connexion est établie. Dans le cas contraire, on ne fait rien, plus exactement le thread est endormi. Pourquoi ne pas profiter de cet état pour tenter des connexions plutôt que de gérer un deuxième thread?

    Bon, j'espère être assez clair.

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/10/2007, 09h42
  2. [VB.NET]Conseils pré-développement
    Par BerSerK dans le forum Windows Forms
    Réponses: 7
    Dernier message: 30/08/2006, 20h35
  3. [Architecture] Conseil pour développement appli Client/Serveur
    Par etiennegaloup dans le forum Développement Web en Java
    Réponses: 11
    Dernier message: 22/01/2006, 11h44
  4. Debutant - demande de conseil
    Par titoftit dans le forum Débuter
    Réponses: 2
    Dernier message: 19/11/2005, 14h13
  5. conseil de développement
    Par koolkris dans le forum Débuter
    Réponses: 4
    Dernier message: 09/11/2004, 13h01

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