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 :

WAIT_ABANDONED n'est pas généré


Sujet :

Threads & Processus C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut WAIT_ABANDONED n'est pas généré
    Bonjour,

    je ne suis pas un expert dans le multhreading et j'aurais donc voulu savoir s'il fallait faire des choses spécifiques pour que la méthode WaitForSingleObject( H_mutex , 0 ) retourne l'évènement WAIT_ABANDONED.
    Pour le moment quand mon mutex est pris par un autre thread, en retour j'ai WAIT_TIMEOUT.

    Declaration de mon Mutex:
    --------------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    H_mutex_RAZ = CreateMutex(NULL, FALSE, "MRAZ");

    Boucle de mon thread de travail:
    -------------------------------
    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    while( ((tCourant - mTpsDebutMS) < mDureeMS) && (Terminated == false) )
    {
        vResWaitMutex = WaitForSingleObject( H_mutex_RAZ , 0 );
     
        switch( vResWaitMutex )
        {
            case WAIT_ABANDONED :
                vFichierTrace << "WaitForSingleObject = WAIT_ABANDONED" << endl;
                usb->acquerrir(vTabData);
            break;
     
            case WAIT_OBJECT_0 :
                vFichierTrace << "WaitForSingleObject = WAIT_OBJECT_0" << endl;
                for(int iV = 0; iV < mNbVoie; ++iV)
                {
                    SONWriteADCBlock(mHFile, iV, vTabData, vLgBuff, mCptData*vLgBuff);
                }
                ++mCptData;
     
                ReleaseMutex( H_mutex_RAZ );
            break;
     
     
            case WAIT_TIMEOUT :
                vFichierTrace << "WaitForSingleObject = WAIT_TIMEOUT" << endl;
            break;
     
     
            case WAIT_FAILED :
                vFichierTrace << "WaitForSingleObject = WAIT_FAILED" << endl;
            break;
     
     
            default :
                vFichierTrace << "WaitForSingleObject = default" << endl;
            break;                    
        }
     
        tCourant = GetTickCount();
    }

    Thread de RAZ prenant le mutex:
    --------------------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    WaitForSingleObject( H_mutex_RAZ , INFINITE );
     
    mCptData = 0 ;
     
    SONCommitFile(mHFile, true);
     
    SONEmptyFile( mHFile );
     
    SONSave(mHFile, -1, 0, true);
     
    Sleep(5000);  // pour test de WaitForSingleObject
     
    ReleaseMutex( H_mutex_RAZ );

    Tout ceci est un prog de test.
    Dans la réalité, pendant que mon thread de RAZ s'execute, le thread de travail doit continuer à faire de l'acquisition de données sur l'USBafin d'éviter un engorgement au niveau de FIFO liées à l'USB.

    Merci

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    As-tu bien compris dans quel cas on obtenait un WAIT_ABANDONED ? Regarde de nouveau la doc MSDN...

    Tant que tu n'as pas le thread PROPRIÉTAIRE du mutex qui se fait flinguer SANS le libérer, ce cas n'arrive jamais. Donc, si tu veux en tester le déclenchement, il te faut flinguer le thread propriétaire : à mon avis, tu vas avoir "pire" à gérer après...

    En temps normal, ce cas n'arrive pas si tu as correctement écrit ton application. Si jamais tu le vois passer, considères plutôt qu'il est urgent d'arrêter ton programme avant que des choses "pires" se passent.
    Ceci étant dit, c'est très bien d'avoir pensé à gérer le cas, et il faut le faire. Mais si ça arrive réellement, arrêtes le plus rapidement (et proprement...) possible ton 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

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Enfin, le thread propriétaire n'a pas forcément besoin de se faire "flinguer": Il peut aussi se terminer normalement, ce qui à ma connaissance, génère aussi un WAIT_ABANDONED s'il n'a pas restitué le mutex avant...
    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.

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Il peut aussi se terminer normalement, ce qui à ma connaissance, génère aussi un WAIT_ABANDONED s'il n'a pas restitué le mutex avant...
    Yep, mais ça, c'est une grosse, grosse erreur de conception...
    C'est pour ça que je disais "ce cas n'arrive pas si tu as correctement écrit ton 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

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    As-tu bien compris dans quel cas on obtenait un WAIT_ABANDONED ? Regarde de nouveau la doc MSDN...
    En effet j'avais mal lu la doc !!!
    Je m'en excuse.

    Il semblerait donc que le comportement que j'obtient est le comportement normal mais que c'est mon interprétation qui est mauvaise. Si j'ai bien compris, si mon mutex est déjà pris, vResWaitMutex = WaitForSingleObject( H_mutex_RAZ , 0 ); me retourne WAIT_TIMEOUT et c'est la que je doit dépilé mon USB.
    Mon "switch() case" devient :
    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
     
    case WAIT_ABANDONED :
        vFichierTrace << "WaitForSingleObject = WAIT_ABANDONED => ERRROR" << endl;
    break;
     
    case WAIT_OBJECT_0 :
        vFichierTrace << "WaitForSingleObject = WAIT_OBJECT_0" << endl;
        for(int iV = 0; iV < mNbVoie; ++iV)
        {
            SONWriteADCBlock(mHFile, iV, vTabData, vLgBuff, mCptData*vLgBuff);
        }
        ++mCptData;
     
        ReleaseMutex( H_mutex_RAZ );
    break;
     
    case WAIT_TIMEOUT :
        vFichierTrace << "WaitForSingleObject = WAIT_TIMEOUT " << endl;
        usb->acquerrir(vTabData);
    break;
     
    case WAIT_FAILED :
        vFichierTrace << "WaitForSingleObject = WAIT_FAILED" << endl;
    break;
     
    default :
        vFichierTrace << "WaitForSingleObject = default" << endl;
    break;



    Il me vient une autre question. Y-aura-t-il une différence conséquente en terme de vitesse d'exécution entre ces 2 codes:

    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
    while( ((tCourant - mTpsDebutMS) < mDureeMS) && (Terminated == false) )
    {
        vResWaitMutex = WaitForSingleObject( H_mutex_RAZ , 0 );
     
        switch( vResWaitMutex )
        {
            case WAIT_OBJECT_0:            
                usb->acquerrir(vTabData);
                for(int iV = 0; iV < mNbVoie; ++iV)
                {
                    SONWriteADCBlock(mHFile, iV, vTabData, vLgBuff, mCptData*vLgBuff);
                }
                ++mCptData;
     
                ReleaseMutex( H_mutex_RAZ );
     
            break;
    .....
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while( ((tCourant - mTpsDebutMS) < mDureeMS) && (Terminated == false) )
    {          
                usb->acquerrir(vTabData);
                for(int iV = 0; iV < mNbVoie; ++iV)
                {
                    SONWriteADCBlock(mHFile, iV, vTabData, vLgBuff, mCptData*vLgBuff);
                }
                ++mCptData;
     
     
    .....
    }

    Merci à tous pour vos réponses

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par gregosKO37 Voir le message
    En effet j'avais mal lu la doc !!!
    Je m'en excuse.
    Pas de soucis, c'est un piège plutôt courant de WFSO, de toutes façons...

    Citation Envoyé par gregosKO37 Voir le message
    Il me vient une autre question. Y-aura-t-il une différence conséquente en terme de vitesse d'exécution entre ces 2 codes:
    Étant donné que tu attends un mutex dans le premier cas, et que tu ne le fais pas dans le deuxième, c'est quasi-certain que le second sera plus rapide... Par contre, un mutex est là pour une bonne raison en général, et tu as de fortes chances d'avoir un crash avec le second code s'il s'avère que le mutex était bel et bien nécessaire.
    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

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Pas de soucis, c'est un piège plutôt courant de WFSO, de toutes façons...

    Étant donné que tu attends un mutex dans le premier cas, et que tu ne le fais pas dans le deuxième, c'est quasi-certain que le second sera plus rapide... Par contre, un mutex est là pour une bonne raison en général, et tu as de fortes chances d'avoir un crash avec le second code s'il s'avère que le mutex était bel et bien nécessaire.
    C'est sûr le mutex est obligatoire !!!!!
    En fait avant j'avais le code sans mutex et une nouvelle fonctionnalité me force à introduire ce mutex. J'espère juste que d'attendre un mutex 0ms ne me fera pas trop perdre en perf car j'ai vraiment beaucoup beaucoup de données qui sont transférées par l'usb et il ne faut surtout pas engorger les FIFO devant l'USB.

    Merci pour les réponses et pour la réactivité.

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Si tu ne l'attends pas (mutex "libre"), la perte de performances sera très faible, même si il y a forcément "perte" quoi qu'il arrive.
    Par contre, forcément, si tu te retrouves réellement bloqué sur le WFSO, ce n'est plus la même histoire.
    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

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Si tu n'as qu'un seul processus et vraiment besoin de performances, tu peux peut-être utiliser une CRITICAL_SECTION plutôt qu'un mutex: C'est censé être plus léger.
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si tu n'as qu'un seul processus et vraiment besoin de performances, tu peux peut-être utiliser une CRITICAL_SECTION plutôt qu'un mutex: C'est censé être plus léger.
    Mon thread est lancé depuis une dll et j'ai un process qui commande cette dll. J'ai donc une commande de ma dll, éxécutée par mon process, qui attaque des objets utilisés par mon thread. Mais mon mutex reste interne à ma dll.
    L'utilisation d'une section critique est adéquat à ton avis ?
    De ce que j'ai lu ça s'utilise comme un mutex. J'ai bien lu cette fois ou je me trompe encore ?
    Si c'est le cas, en plus, ça n'oblige pas à bloquer le thread de ce que je comprend et ç'a m'arrange bien.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Une section critique, ça bloque le thread autant qu'un mutex.
    Mais les différences majeures sont:
    • Ça ne marche qu'au sein du même processus, alors que les mutexes peuvent être partagés entre plusieurs
    • Ça n'est pas compatible avec les fonctions d'attente ordinaires de Windows. Si tu es habitués aux objets de synchronisation *n*x ou si tu n'utilises que WaitForSingleObject(), ça ne fait pas de différences. Mais si ton programme est basé sur WaitForMultipleObjects(), tu as besoin d'utiliser un mutex à la place.

    Pour ton cas, je pense que la section critique est appropriée.
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Février 2010
    Messages : 6
    Par défaut
    Merci
    Je vais m'empressé de tester tout ça.

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Ça ne marche qu'au sein du même processus, alors que les mutexes peuvent être partagés entre plusieurs
    Juste pour info : on peut l'utiliser entre deux processus, mais cela demande à poser la CS dans de la mémoire partagée, avec les problèmes et inconvénients que cela pose derrière bien sûr.
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/01/2010, 14h13
  2. Programmer encore en VB 6 c'est pas bien ? Pourquoi ?
    Par Nektanebos dans le forum Débats sur le développement - Le Best Of
    Réponses: 85
    Dernier message: 10/03/2009, 14h43
  3. [VB6] générer un recordset qui n'est pas lier à un bdd
    Par damyrid dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 05/06/2003, 17h48
  4. Index n'est pas a jour
    Par touhami dans le forum Paradox
    Réponses: 5
    Dernier message: 11/12/2002, 14h47

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