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

Delphi Discussion :

[D7][Mutex]Exclusion inter application


Sujet :

Delphi

  1. #1
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut [D7][Mutex]Exclusion inter application
    Hello,

    Contexte :

    Deux applications sur un même PC.

    Ma première application crée un mutex (CreateMutex) avec le nom d'objet "Toto". Le resultat du CreateMutex est le handle du mutex crée et vaut par exemple : 1724.

    Ma seconde application crée un mutex (CreateMutex) avec le nom d'objet "Toto". La création est censé échouer car le mutex a déjà été crée. La seconde application change alors de tactique et récupère le handle du mutex "Toto" (OpenMutex). Le resultat du OpenMutex est le handle du mutex récupéré et vaut par exemple : 2628.

    Question1 :
    Le handle du mutex crée/récupéré dans les deux applications ne devraient-il pas être le même ? par exemple 1724 dans les deux applications ?

    Question2 :
    En utilisant ce mutex dans mes deux application avec les fonction WaitForSingleObject et ReleaseMutex, vais-je réussir à éviter un accès concurent à une même ressources par les deux applications ?

    Vos lumières sur ces deux questions me seraient bien utiles... Si j'ai dit des bétises, n'hésitez pas non plus à me rectifier.
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  2. #2
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Personne ne saurai me répondre ?
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 731
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 731
    Points : 15 136
    Points
    15 136
    Par défaut
    Mets-nous un bout de code, on pourra tester !
    --
    jp
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Membre chevronné

    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 288
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2002
    Messages : 1 288
    Points : 1 936
    Points
    1 936
    Par défaut
    Pour tester si le mutex existe déjà: [FAQ]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      SetLastError(NO_ERROR);
      CreateMutex (nil, False, PChar(MonNomDeMutex));
      if GetLastError = ERROR_ALREADY_EXISTS then
    Delphi 7/XE2/XE3
    C#
    Oracle 9i à 12c
    SQL Server 2008 à 2014

  5. #5
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    Question2 :
    En utilisant ce mutex dans mes deux application avec les fonction WaitForSingleObject et ReleaseMutex, vais-je réussir à éviter un accès concurent à une même ressources par les deux applications ?
    Si tu récupère le même identifiant de mutex, alors oui. Les mutex ont étés crés pour ça: gérer les accès au ressources entre des threads qui s'execute séparemment. Attention quand même de na pas bloquer ton appli ou à creer des situations de famines.

    @+.
    For crying out loud !

  6. #6
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Voici en simplifié ce que je fait... Je vous l'épure un peu sinon, personne ne voudra s'y plonger

    J'ai développé la fonction TraceMessage qui ajoute dans un fichier une chaine passée en paramètre.
    Chaque programme dans lequel j'ai inclue l'unité contenant TraceMessage peut ainsi espionner son fonctionnement interne... Le fichier "espion" est généré dans le même path que l'application qui espionne.
    Ainsi, si deux applications du même répertoire espionnent, elles écrivent dans le même fichier. Je tente de mettre en place un système de mutex afin d'éviter les conflits d'accès à l'espion, sachant que dans le pire des cas, l'espion ne doit pas planter le programme qui espionne.

    Voici mon pseudo code :


    Deux variables globales :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        g_ThreadGestionEspion : TThreadGestionEspion ; //* Thread permettant de gérer les accès concurents a l'espion au sein d'une même application.
        g_SpyMutex : THandle = 0 ; //* Handle du mutex.
    Pseudo-code de la fonction TraceMessage
    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
    procedure TraceMessage(sMessage : string);
        begin
            // Création ou récupération du mutex d'accès au fichier lstmess.csv
            SetLastError(NO_ERROR);
            if(g_SpyMutex = 0)then
            begin
                g_SpyMutex := CreateMutex(nil, false, PChar(sNomMutex)); // <= Création du mutex
            end;
            if (GetLastError=ERROR_ALREADY_EXISTS) then
            begin
                g_SpyMutex := OpenMutex(MUTEX_ALL_ACCESS , false, PChar(sNomMutex)); // <= Recuperation du mutex si déjà existant
            end;
    
            // Réservation du mutex
            WaitForSingleObject(g_SpyMutex,INFINITE); // <= Utilisation du mutex
            try
                // Création de l'objet à tracer dans l'espion
    	    SpyMessage := TSpyMessage.create(...);
                // Création ou réutilisation du thread de gestion de l'espion.
                if(not(Assigned(g_ThreadGestionEspion)))then
    	    begin
    	    	g_ThreadGestionEspion := TThreadGestionEspion.create(false,true);
    	    end;
    	    // Dépot de l'objet à tracer dans l'espion sur le dessus de la pile des objets à tracer.
                g_ThreadGestionEspion.Addmessage(SpyMessage);
            Finally
                // Libération du mutex d'accès au fichier lstmess.scv
                ReleaseMutex(g_SpyMutex);// <= Liberation du mutex
            end;
        end;
    Et maintenant, voici le pseudo code du thread qui dépile les messages et qui, lui seul, est autorisé à écrire dans le fichier espion. Evidemment, Si deux applications espionnent dans le même répertoire, chaque appli aura son thread d'écriture dans l'espion. C'est pourquoi les threads utilisent le mutex "g_SpyMutex" créé dans TraceMessage.

    Un morceau de la déclaration de la classe TThreadGestionEspion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      TThreadGestionEspion = class(TThread)
      private
        { Déclarations privées }
        m_slMessages : tstringList ;
       [...etc...]
    Pseudo-code de la fonction Execute du TThreadGestionEspion :
    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    procedure TThreadGestionEspion.Execute;
    	var
    	sMessage : string ;
    	slListeErreurs : tstringList ;
        begin
            repeat
                sleep(10);
                Application.ProcessMessages();
                // Réservation du mutex
                WaitForSingleObject(g_SpyMutex,INFINITE);// <= Utilisation du mutex
                try
                    if(m_slMessages.count>0)then
                    begin
                        // Récupération du plus vieux SpyMessage en attente d'insertion dans le fichier lstmess.csv
                        m_slMessages := Liste.strings[0];
                        
                        slListeErreurs.Clear ;
                        if(FileExists(ExtractFilePath(sModuleName)+'lstMess.csv')=true)then
                        begin
    	                    try
    	                        slListeErreurs.LoadFromFile(ExtractFilePath(sModuleName)+'lstMess.csv');
    	                        Except on E:exception do
    	                        begin
    	                            // Rien du tout, ce n'est pas grave.
    	                            Continue ;
    	                        end;
    	                    end;
                            // On teste la capacité du fichier pour éviter les débordements
                        end;
                        slListeErreurs.Insert(0,sMessage);
                        try
                            slListeErreurs.SaveToFile(ExtractFilePath(sModuleName)+'lstMess.csv');
                            bSuccesSpy := true ;
                            except on E : exception do
                            begin
                                // Rien du tout, ce n'est pas grave.
                                Continue ;
                            end;
                        end;
                        if(bSuccesSpy)then
                        begin
                            // Suppression du SpyMessage que l'on viens de réussir à insérer dans le fichier lstmess.csv
                            TSpyMessage(m_slMessages.Objects[0]).free ;
                            m_slMessages.Delete(0);
                        end;
                    end;
                Finally
                    // Libération du mutex d'accès au fichier lstmess.scv
                    ReleaseMutex(g_SpyMutex);// <= Liberation du mutex
                end;
            until (terminated) ;
            slListeErreurs.Free ;
            slListeErreurs := nil ;
        end;
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  7. #7
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    J'voue que j'ai vraiment la flemme de me lancer dans un code à base de Mutex.... .
    Pourrais-tu simplement indiqué la ligne de création avec son handle et celles qui récupèrent un mauvais handle?

    J'aurais quand même deux questions:
    1) Est-ce que ton programme fonctionne si la récupération du mutex appartient à la même application que celle de sa création?
    2)Est-ce que un second mutex est crée (c'est envisagle puisque tu as deux handle différents)?

    @+.
    For crying out loud !

  8. #8
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Voilà, j'ai mis un peu de gras dans mon pseudo-code pour vous en faciliter la lecture.

    Comme j'espionne également l'utilisation des mutex afin de comprendre où ça pourrait clocher, voici un extrait de ma trace révélateur du problème :

    Une dll de mon cru utilise l'espion via la fonction TraceMessage
    Le programme chargé de tester cette même dll utilise la même fonction pour s'espionner lui même.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Le plus récent
    Date			Application		NomFonction		Opération réalisée		N°Hdle utilisé	Nom Mutex utilisé pour le CreateMutex ou le OpenMutex
    16/10/2006 09:32:56	Dtt.dll (2.2.0.0) 	TraceMessageV02() 	ReleaseMutex		 	3728		
    16/10/2006 09:32:56	Dtt.dll (2.2.0.0) 	TraceMessageV02() 	WaitForSingleObject	 	3728	
    16/10/2006 09:32:56	Dtt.dll (2.2.0.0) 	TraceMessageV02() 	OpenMutex			3728		SPYMUTEXDDOCUMENTSANDSETTINGSAWATREJMYDOCUMENTSPROGMKSSOURCESDTT2
    16/10/2006 09:32:56	Testeur_Dtt ()		TraceMessageV02() 	ReleaseMutex		 	3772		
    16/10/2006 09:32:56	Testeur_Dtt ()		TraceMessageV02() 	WaitForSingleObject	 	3772	
    16/10/2006 09:32:56	Testeur_Dtt ()		TraceMessageV02() 	CreateMutex			3772		SPYMUTEXDDOCUMENTSANDSETTINGSAWATREJMYDOCUMENTSPROGMKSSOURCESDTT2
    Le plus vieux
    Je n'ai mis que le début de la trace, mais par la suite, chacune des app continue à utiliser son mutex dans son coin...
    Je n'utilise jamais CloseHandle() sur le mutex qui nous intéresse car je n'ai pas moyen de savoir si le mutex est encore où non utilisé par une application externe.

    Je rappèle mon problème : Je m'étonne que le numéro du Handle ne soit pas le même dans mes deux app et je me demande donc si ma protection par mutex est efficace...
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

Discussions similaires

  1. Communication inter application
    Par aure298 dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 4
    Dernier message: 04/08/2009, 21h57
  2. [Cluster] Communication inter-applications
    Par polo54 dans le forum Websphere
    Réponses: 3
    Dernier message: 21/05/2009, 00h35
  3. Communication inter application c#
    Par chental dans le forum C#
    Réponses: 6
    Dernier message: 20/03/2008, 17h00
  4. [gtkmm] communication inter application ?
    Par drKzs dans le forum GTK+ avec C & C++
    Réponses: 0
    Dernier message: 22/01/2008, 18h21
  5. communication inter application
    Par austin P. dans le forum Spring
    Réponses: 4
    Dernier message: 09/05/2007, 22h00

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