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

Réseau C Discussion :

Comment partager un mutex entre les callback d'un programme


Sujet :

Réseau C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut Comment partager un mutex entre les callback d'un programme
    Bonjour,
    je voudrais savoir si les fonctions callback sont executées en tant que thread système ou en tant que thread du programme qui s'execute.

    Si on elles prennent le temps du programme, comment peut-on executer deux "chemins" en même temps :
    d'une part le fonction Winmain qui se s'arrète qu'à la fin : while (GetMessage ...)" et d'autre part la callback.

    Si elles prennent le temps du système, comment peut-on partager un mutex entre les threads de toutes les callback qui s'executent en même temps?
    Il faut faire un appel à CreateMutex dans la Winmain et faire un appel à OpenMutex puis à WaitForSingleObject dans les callback quand on veut modifier la donnée ou bien il faut faire un appel à CreateMutex dans les callback quand on veut modifier la donnée ou il faut faire autre chose?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 578
    Points
    41 578
    Par défaut
    À part pour les hooks et un callback des services, à ma connaissance tous les callbacks sont exécutés dans un thread du procesus qui les règle.

    Les callbacks de fenêtre et boîte de dialogue sont toujours éxécutés dans le thread auquel appartient la fenêtre: Ils sont appelés lors du DispatchMessage() pour les messages "postés", et généralement plus tôt (notamment lors du GetMessage()) pour les messages "envoyés" par les autres threads, qui sont plus urgents. Sachant qu'il peut y avoir des boucles de message dans la boucle de message, etc. (Par exemple, si le callback appelle MessageBox() suite à un clic sur un bouton, etc.)

    Le callback d'EnumWindows() ou EnumThreadWindows() est appelé par la fonction elle-même, plusieurs fois durant son exécution.

    En tout cas, les callbacks de fenêtre Windows ne seront jamais appelés quand on ne s'y attend pas: La programmation fenêtrée est de la programmation événementielle et non de la programmation interruptible.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Donc deux fonctions callback ne peut pas s'executer en même temps ? Donc pas besoin de partage de mémoire.

    Et dans un boucle comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    les messages sont envoyés à la callback par les focntions GetMessage et DispachMessage ?

    C'est quoi la programmation interruptible ?

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 578
    Points
    41 578
    Par défaut
    Deux fonctions callback ne peuvent s'exécuter en même temps, mais il faut savoir qu'une fonction callback peut indirectement en appeler une autre ou même s'appeler elle-même (Si elle fait un MoveWindow() par exemple, ou tout simplement un SendMessage() sur sa propre fenêtre).

    La programmation interruptible, c'est notamment jouer avec les signaux : Un signal peut arriver absolument à tout moment sur le processus. C'est parfois utilisé sous Linux avec les sockets, entre autres. Sous Windows, ce n'est pratiquement jamais utilisé.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Ah non, y'a un problème :

    j'ai équipé la boucle de la Winmain comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while (GetMessage (&messages, NULL, 0, 0))
    {
        sprintf (chaine, "Message envoyé (message : %4lu, wParam : %10lu, lParam : %10lu).\r\n", messages.message, messages.wParam, messages.lParam);
        WriteFile (hFichier, chaine, 76, &buffer, NULL);
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    et voilà le résultat (tous ces messages proviennent non pas de la Winmain mais de la callback) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Message reçu (message :   36, wParam :          0, lParam :    2291600).
    Message traité (message :   36, wParam :          0, lParam :    2291600).
    Message reçu (message :  129, wParam :          0, lParam :    2291576).
    Message traité (message :  129, wParam :          0, lParam :    2291576).
    Message reçu (message :  131, wParam :          0, lParam :    2291632).
    Message traité (message :  131, wParam :          0, lParam :    2291632).
    Message reçu (message :    1, wParam :          0, lParam :    2291544).
    Message traité (message :    1, wParam :          0, lParam :    2291544).
    Message reçu (message :   24, wParam :          1, lParam :          0).
    Message traité (message :   24, wParam :          1, lParam :          0).
    Donc la majorité des appels se fait hors de la Winmain, à moins que DispatchMessage ou GetMessage envoient plusieurs messages à la fois à la callback.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 578
    Points
    41 578
    Par défaut
    DispatchMessage() ne dispatche que le message "posté" retourné par GetMessage(), mais avant de retourner, GetMessage() a déjà dispatché tous les messages "envoyés", comme indiqué dans sa doc.

    Sans compter que le traitement de certains messages par DefWindowProc() déclenche une boucle de messages imbriquée: Par exemple, si tu cliques sur la barre de titre pour déplacer la fenêtre, DefWindowProc() ne retourne pas tant que le bouton n'est pas relaché: Il y a une boucle de messages interne.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Donc si j'ai bien compris, GetMessage appelle la callback pour chaque message dans la thread queue et de temps en temps au lieu de faire ça il crée une structure et retourne une valeur. Mais alors quand il n'y a aucun message, qu'est ce qui se passe?
    (Ma doc n'est pas très claire en fait)

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 578
    Points
    41 578
    Par défaut
    Tant qu'il n'y a aucun message, GetMessage() attend.

    Et ce n'est pas "de temps en temps": Ça dépend si c'est un message "posté" ou un message "envoyé".

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Au moins comme ça je vais progresser en anglais, ....

    Ben merci, je vais lire tous ça (quand mon explorateur aura affiché la page msdn bien sur, à croire que msdn fait exprès de ralentir encore plus les connexions 56k...)

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Une dernière précision : si Windows ou une autre thread envoie un message à ma callback, mais que celle-ci fait déjà quelque chose (elle à par exemple été appellée par DispatchMessage), la thread appelante doit bien attendre que la callback retourne et que ma boucle de message appelle GetMessage? Ainsi GetMessage permet l'appel succéssif de ma callback pour tout les messages envoyés puis quand il n'y a plus de thread qui envoie un message, GetMessage retourne le first in message de ma thread message queue.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 578
    Points
    41 578
    Par défaut
    Si Windows ou un autre thread envoie un message à la fenêtre (et non pas directement à la callback), le thread expéditeur est bloqué jusqu'à ce que le thread auquel appartient la fenêtre destinataire retourne dans un état où il peut recevoir des messages.
    SendMessage() ne retournera qu'après que le thread destinataire ait traité le message et fourni une réponse, soit quand le callback retourne une valeur, soit si le callback appelle ReplyMessage() pour débloquer immédiatement le thread expéditeur.

    Un thread peut recevoir un message "envoyé":
    • Dans un GetMessage() (bloquant)
    • Dans un PeekMessage()
    • Dans un SendMessage() vers un autre thread (ou dans un SendMessageTimeout() sans le flag SMTO_BLOCK) (bloquant)
    • Dans tout ce qui contient une boucle de messages, car une boucle de messages appelle forcément GetMessage() ou PeekMessage().

    Par contre, le thread n'est pas en état de recevoir des messages pendant un traitement simple dans la callback, ou un SendMessage() dans le même thread, ou un Sleep(), ou un EnumWindows(), etc.
    Ainsi, le seul moyen pour qu'un thread reçoive un message pendant qu'il est en train d'en traiter un autre, c'est de faire une opération pouvant causer cela: Appeler une fonction avec boucle de messages interne, ou faire un SendMessage() vers un autre thread.
    Fonctions avec des boucles de message internes:
    • MessageBox(), DialogBox(), et toutes leurs soeurs (mais PAS CreateDialog() et ses soeurs).
    • DefWindowProc() pour certains clics de souris, notamment sur le menu, sur la barre de titre, sur les bords pour redimensionner, etc.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 217
    Points : 105
    Points
    105
    Par défaut
    Merci beaucoup, j'en sais assez pour faire tous ce que je veux faire.

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

Discussions similaires

  1. comment partager des données entre les sessions
    Par jesslegende dans le forum Langage
    Réponses: 9
    Dernier message: 12/03/2011, 23h16
  2. [WinForms]Comment partager des objets entre threads ?
    Par AiSpirit dans le forum Général Dotnet
    Réponses: 3
    Dernier message: 16/08/2006, 08h57
  3. [javaBean + JSP] comment partager un objet entre les page JSP
    Par subzero82 dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 31/05/2006, 18h48
  4. Réponses: 7
    Dernier message: 06/04/2006, 18h17
  5. comment faire le choix entre les SGBD sous delphi
    Par redhammd dans le forum Bases de données
    Réponses: 1
    Dernier message: 27/11/2005, 11h39

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