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 :

Thread -> WaitForSingleObject() && Application -> Bloquée


Sujet :

Threads & Processus C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut Thread -> WaitForSingleObject() && Application -> Bloquée
    Bonjours à tous !

    Je ne comprends pas bien le fonctionnement ci-après :

    J'ai une fonction qui lance deux threads. Ces deux threads sont synchronisés entre eux. Normalement, pendant qu'ils s'exécutent, je devrais être censé pouvoir naviguer à souhait sur l'interface graphique de mon application. Néanmoins, l'usage de WaitForSingleObject m'empêche vraisemblablement de le faire : l'application est bloquée.

    NB : Les deux threads sont exécutés de leur première à leur dernière instruction.

    Sauriez-vous ce qui cloche ?

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 081
    Points : 12 138
    Points
    12 138
    Par défaut
    WaitForSingleObject fait attendre le thread qui l'appel jusqu'à ce que le handle en paramètre soit signalé.
    Si le thread qui appel WaitForSingleObject est le thread graphique, l'affichage est bloqué.
    Je pense que vous avez mal compris l'utilisation de WaitForSingleObject.

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    Bonjour,
    le WaitForSingleObject est vraiment utile des le moment ou l'application va se fermer afin que tous les processus fils soit bien mort avant la mort du processus père afin d'éviter des problèmes de processus fantômes.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par bacelar Voir le message
    WaitForSingleObject fait attendre le thread qui l'appel jusqu'à ce que le handle en paramètre soit signalé.
    Si le thread qui appel WaitForSingleObject est le thread graphique, l'affichage est bloqué.
    Je pense que vous avez mal compris l'utilisation de WaitForSingleObject.
    Hum... en fait, les deux threads sont complètement indépendants du thread graphique. Grosso modo, sur l'interface graphique il y a un bouton. C'est en cliquant sur ce bouton que les deux threads sont lancés, et pourtant toute l'application est bloquée. Je pense que tout ceci est causé par les appels à WaitForSingleObject().

    Je signale des événements selon ce procédé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Thread1
              // Création de l'événement event1
              [...]
              WaitForSingleObject(event1, INFINITE);
              ResetEvent(event1);
              [Opérations]
              SetEvent(event2);
    Thread2
              // Création de l'événement event2
              [Calculs]
              SetEvent(event2);
              WaitForSingleObject(event2,INFINITE);
              ResetEvent(event2);
    Je précise que les événements sont créés à l'état non signalé. Ces deux threads sont donc plus ou moins bloquants, mais tout ça ne devrait pas bloquer l'application elle-même, si ?

    @jouana : comment pourrais-je m'en passer dans mon cas ?

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    tu utilise quoi comme lib graphique??

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par jouana Voir le message
    tu utilise quoi comme lib graphique??
    MFC.

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    C'est pour lucratif un projet a but lucratif?
    sinon y a Qt qui vaut le coup

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par jouana Voir le message
    C'est pour lucratif un projet a but lucratif?
    sinon y a Qt qui vaut le coup
    C'est pour un logiciel métier qui est développé depuis 20 ans...

    Et quant à mon problème, qu'en penses-tu ?

  9. #9
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Points : 654
    Points
    654
    Par défaut
    bah je ne connais pas trop MFC mais tu doit avoir des hook pour tes event a la place de tes threads c'est pas trop comme sa que tu fait de l'evenmentiel

  10. #10
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Plusieurs remarques concernant ton pseudo code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Thread1
              // Création de l'événement event1
              [...]
              WaitForSingleObject(event1, INFINITE);
              ResetEvent(event1);
              [Opérations]
              SetEvent(event2);
    Si l'event2 n'est pas créé, SetEvent(event2) ne sert à rien (et génère une erreur). Ceci peut se produire si le thread2 n'est pas encore parti puisque c'est lui qui créé l'event2


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Thread2
              // Création de l'événement event2
              [Calculs]
              SetEvent(event2);
              WaitForSingleObject(event2,INFINITE);
              ResetEvent(event2);
    Le thread2 va partir immédiatement puisque l'event2 est positionné et ensuite on attend dessus avet de le resetter, c'est le but ?

    Dans aucun des 2 thread je ne vois le SetEvent(event1), un oubli ou bien c'est fait ailleurs ?

    En régle générale, avant de créer les thread, il faut créer les event
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 081
    Points : 12 138
    Points
    12 138
    Par défaut
    Il fait quoi, le thread graphique, après avoir créé les 2 autres threads ?

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Dans aucun des 2 thread je ne vois le SetEvent(event1), un oubli ou bien c'est fait ailleurs ?
    C'était une erreur de ma part :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Thread2
              // Création de l'événement event2
              [Calculs]
              SetEvent(event1);
              WaitForSingleObject(event2,INFINITE);
              ResetEvent(event2);
    C'est l'événement 1 que je signale ici. En amont dans le code, je crée un événement dans le thread 1 et j'attends qu'il soit signalé par le thread 2. Il est signalé après la création des événements qui seront utilisés. Dans le thread 1, j'utilise WaitForSingleObject() après avoir également créé les événements. En résumé, tous mes événements sont créés avant de procéder aux calculs et aux opérations.

    @bacelar : Le thread graphique doit permettre à l'utilisateur de lancer d'autres opérations pendant que les deux autres tournent.

    Hum... le problème vient peut-être du fait que le thread 1 met à jour une zone de l'interface graphique.

    Edit : En fait j'essaye de mettre à jour une barre de progression en fonction de l'avancée d'un calcul. Ce qui serait terminé si il n'y avait pas ce caractère bloquant.

  13. #13
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Plumb Voir le message
    Hum... le problème vient peut-être du fait que le thread 1 met à jour une zone de l'interface graphique.

    Edit : En fait j'essaye de mettre à jour une barre de progression en fonction de l'avancée d'un calcul. Ce qui serait terminé si il n'y avait pas ce caractère bloquant.
    Il le fait comment en envoyant un message à l'interface graphique (Send/Post Message(WM_USER, ...)) ou bien en agissant directement sur l'interface graphique.

    Pour info, il faut que ton thread envoie un message spécifique à l'interface graphique et l'interface graphique en recevant ce message spécifique va mettre à jour l'objet graphique.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Il le fait comment en envoyant un message à l'interface graphique (Send/Post Message(WM_USER, ...)) ou bien en agissant directement sur l'interface graphique.

    Pour info, il faut que ton thread envoie un message spécifique à l'interface graphique et l'interface graphique en recevant ce message spécifique va mettre à jour l'objet graphique.
    J'utilise une redéfinition de la classe CProgressCtrl. Quand je modifie le champ texte de la barre de progression, par exemple, une fonction de redimensionnement est appelée. Dans le code je peux y lire des appels à UpdateWindow(), MoveWindow(). Après t'avoir lu, j'ai commenté les appels à la fonction pour changer le texte, et il ne restait que des fonctions de modification de la position, de pas, et des StepIt(), qui elles font directement appel aux fonctions de la classe mère CProgressCtrl. D'après le code source, cette classe (CProgressCtrl) fonctionne par envoi de messages.

    C'est donc bien un problème lié à des modifications sur la fenêtre principale. Si dans mon thread 1 je commente tous les appels inhérents à la barre de progression, l'application n'est plus bloquée.

  15. #15
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Un thread de travail (tes threads 1 et 2) sont probablement des thread de travail ou encore Working Thread ne doit pas modifier l'interface graphique.

    Il doit :
    • Envoyer un message spécifique à l'interface graphique WM_USER + x (à définir, c'est ton message utilisateur) avec des paramètres wParam et lParam qui permettent à l'interface graphique de savoir ce que veut le working thread. Pour cela, il faut que le working thread connaisse le handle HWND (et pas le CWnd *) de l'interface graphique. En général, c'est passé en paramètre lors de la création du thread.
    • Ce message doit être envoyé par SendMessage ou PostMessage (SendMessage est bloquant et attend que le message soit traité par la l'interface graphique, PostMessage ne fait que poster et retourne immédiatement)
    • L'interface graphique doit intercepter le message WM_USER + x dans le MESSAGE_MAP et faire le traitement en fonction des différents paramètres reçus (dans wParam et lParam)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Un thread de travail (tes threads 1 et 2) sont probablement des thread de travail ou encore Working Thread ne doit pas modifier l'interface graphique.

    Il doit :
    • Envoyer un message spécifique à l'interface graphique WM_USER + x (à définir, c'est ton message utilisateur) avec des paramètres wParam et lParam qui permettent à l'interface graphique de savoir ce que veut le working thread. Pour cela, il faut que le working thread connaisse le handle HWND (et pas le CWnd *) de l'interface graphique. En général, c'est passé en paramètre lors de la création du thread.
    • Ce message doit être envoyé par SendMessage ou PostMessage (SendMessage est bloquant et attend que le message soit traité par la l'interface graphique, PostMessage ne fait que poster et retourne immédiatement)
    • L'interface graphique doit intercepter le message WM_USER + x dans le MESSAGE_MAP et faire le traitement en fonction des différents paramètres reçus (dans wParam et lParam)
    De cette manière l'interface ne serait plus bloquée, même si elle est mise à jour ?

    Je vais étudier tout ça, merci.

  17. #17
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Plumb Voir le message
    De cette manière l'interface ne serait plus bloquée, même si elle est mise à jour ?
    L'interface fait son boulot de gestion des objets graphiques et du raffraichissement.

    Les thread font leur boulot (du calcul ou de trucs de longue haleine) et de temps en temps envoient un message à l'interface graphique pour lui demander de mettre à jour un truc ou un bidule graphique.

    C'est comme cela que cela doit marcher
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  18. #18
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Oui, mais pendant la mise à jour, l'utilisateur ne pourra toucher à rien dans l'interface ?

  19. #19
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Si si, mais les événements sont sérialisés par l'interface graphique donc il n'y aura pas de conflit.

    Par contre, là où il peut y avoir des problème c'est si tu as des boutons qui ont des actions contradictoires dans le genre "stop" du thread même si aucun thread n'est lancé au start d'un thread déjà lancé.

    Dans ce cas, soit tu rajoutes des tests dans les fonctions de traitement des boutons, soit tu actives et désactives les boutons pour refléter l'état du système (ce que je ferais).

    Il n'y a rien de pire que de cliquer sur le bouton "stop" et de prendre un message d'erreur "Pas de thread à stopper", autant désactiver le bouton.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 081
    Points : 12 138
    Points
    12 138
    Par défaut
    Si mes souvenirs sont bons, c'est plus WM_USER + x mais WM_APP + x dû à de sombres histoires de framework additionnels.

    soit tu actives et désactives les boutons pour refléter l'état du système (ce que je ferais).
    Pour moi, c'est ceinture et brettelles, donc désactivation ET "rajoutes des tests dans les fonctions de traitement ", car la prise en compte du changement d'état peut avoir une certaine latence.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 9
    Dernier message: 04/04/2011, 10h20
  2. mon application est bloquée, freeze
    Par ericaix13 dans le forum C#
    Réponses: 11
    Dernier message: 28/10/2010, 20h07
  3. L'application se bloque lors de l'execution
    Par charouel dans le forum Windows Forms
    Réponses: 5
    Dernier message: 22/10/2009, 18h31
  4. [Serveur J2EE] Faire tourner un thread dans un serveur d'applications
    Par Pierre-Yves VAROUX dans le forum Java EE
    Réponses: 3
    Dernier message: 13/10/2005, 14h10

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