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

Langage Delphi Discussion :

Question de synchronisation


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Points : 107
    Points
    107
    Par défaut Question de synchronisation
    Bonjour,

    Je voudrais savoir si il est possible d'empecher 2 utilisateurs différents, ayant exécuter le meme programme mais sur des pc différents, d'exectuer des routines en meme temps.

    Dans le cas qui me préoccupe, je doit faire un vérification dans ma DB et si c est bon je doit y faire un insert. Mais si 2 personne ont vérifiés en meme temps, il se pourrait que se soit bon pour les 2 et donc qu'ils veuillent inserer en meme temps ce qui me pose problème.

    Donc je pensait éventuellement à un bloc synchronise mais je ne sais pas si ca marche pour 2 instances du programme...

    D'avance merci

    bEn

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Points : 485
    Points
    485
    Par défaut
    pour des problemes d'acces a un systeme a entree unique, il existe plusieurs solutions (recherche sur google avec algorithmie).

    L'une d'elle est d'utiliser les semaphores.
    Le principe est tres simple, tu place un "compteur d'utilisation".
    C'est a dire, des que tu vas effectuer ton operation d'insertion, tu met une variable à 1 (ou vrai ou autre chose qui puisse la differencier de son etat "standard"). Quand tu as finis, ton operation, tu la remet dans son etat normal.
    Dans ton cas, ca donnerait quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    While (MaVariable <> 0) do
      Application.ProcessMessages; //Tu peux meme faire une petite animaltion histoire de dire que c'est en attente
    try
      MaVariable:=1;
      VerificationBDD;
      Insertion;
    finally
      MaVariable:=0;
    end;

  3. #3
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Points : 107
    Points
    107
    Par défaut
    Oui ok mais ca ca fonctionne que pour une seule instance du programme non?

    Comment fait on communiquer les 2 instance du programme???

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Points : 485
    Points
    485
    Par défaut
    Utilise le systeme de semaphore du systeme (Windows en dispose mais je connais pas pour linux).

    Cherche les exemple pour n'avoir qu'une seule instance d'un programme avec Delphi, la plupart sont codés avec l'enregistrement d'une semaphore systeme. Ou cherche direct sur la MSDN

    En fait, c'est comme une variable interne excepte que c'est gere par le systeme.

  5. #5
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    ou alors tu utilises les propriétés de verrouillages des BD...

    Tu te fais une table dédiée a ca.
    Pour le traitement X, il y aura la ligne X dans cette table.

    Tu ouvres ta ligne X en édition qd tu commences le traitement (qui que ce soit), tu la cancel qd le traitement est fini.

    Si un autre utilisateur tente de faire le traitement, pendant que la ligne X est en édition --> c'est refusé !

    et la, pas de problème de nombre de user

    Plus simple à mettre en place que les sémaphores en tout cas, et efficace

    en gros

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Se positionner sur LigneX de la table
    Si Table pas en edition alors
      try
      Table.Edit
      Traitement
      Finally
      Table.cancel;
      end;

  6. #6
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Points : 107
    Points
    107
    Par défaut
    Oui mais je suis sous Delphi 8 et je ne trouve pas les commandes genre CreateSemaphore, ... Que se soit dans l aide ou en tapant directement le code il ne le reconnait pas...

    Peut etre via les lock DB je vais peut etre essayer comme ca...

  7. #7
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    le système de verouillage de TicTacToe est plus simple à mettre en oeuvre mais il y a aussi des danger avec :
    - Si l'appli cliente qui a initier le changement se plante alors que le traitement n'est pas terminé jusqu'au bout, tout le monde et bloqué.
    - Si le serveur se plante aussi en se moment alors pareil.


    A+

  8. #8
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Andry a raison dans une certaine mesure

    Je ne mets pas un flag sur la ligne (qui serait donc indéfiniment inchangée en cas de plantage), mais juste en édition.

    Si c'est un plantage serieux, de toute manière d'autres élements de ta base seront certainement endommagées, et a ce moment la, la priorité ne sera pas ton traitement, mais la réparation de ta base, et donc la fermeture de toutes tes tables (y compris ta table de verrouillage)

    Si c'est un plantage léger, ta table aura de très bonne chance d'être "cancélée", et de rendre le verrou. (Perso j'utilise pourtant paradox qui est pas réputée pour être hyper solide, et des lignes qui restent en édition après plantage, j'en ai jamais ou presque).

    Si le traitement plante, le finally prend le relai et abandonne l'édition sur la table.

    Est-ce plus fiable en cas de plantage avec les sémaphores (c'est vraiment une question, perso je sais pas.. ? ).

  9. #9
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Points : 485
    Points
    485
    Par défaut
    Oui mais je suis sous Delphi 8 et je ne trouve pas les commandes genre CreateSemaphore, ... Que se soit dans l aide ou en tapant directement le code il ne le reconnait pas...
    Dans l'aide, c'est normal, vu que c'est une fonction de l'API de windows, il faut rechercher dans le SDK.
    Dans Delphi, c'est plus etonnant, je viens de rechercher, la fonction est bien dans l'unit "windows" dans D7.

    Plus simple à mettre en place que les sémaphores en tout cas, et efficace
    La simplicite est toute relative, ca demande un acces en plus a la BDD et ca occupe le proc a chaque fois que tu fais ta requete + gros bug si une erreur survient pendant ce temps: tu n'as pas de gestionnaire d'erreur au niveau de la BDD mais seulement au niveau du prog.

    C'est pas que je sois un fervant defenseur de mes idees mais tout de meme, il existe des mecanismes tout pret, pourquoi ne pas les utiliser :
    -semaphore
    -mutex
    -operations atomiques

    semaphore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    MySemaphore := CreateSemaphore(Nil, DebutCpt{1}, MaxCpt {1}, nil { ou donne un nom a ta semaphore});
    WaitForSingleObject(MySemaphore, {Mettre Infinite ou un temps en milliseconde qui servira de time-out});
    //Traitement que tu veux.
    ReleaseSemaphore(MySemaphore, 1, nil);
    Comme tu peux le voir sur ce premier exemple, c'est tres simple et ca permet meme de mettre un time out en verifiant la sortie de WaitForSingleObject.
    Si tu veux que ca marche en inter-process, n'oublie pas de nommer ta semaphore

    Au passage, principe de la semaphore (a ce que j'ai compris): creer un compteur avec un valeur initialise, a chaque fois que tu veux acceder a un objet, ca decremente le compteur puis reincremente a la fin.
    Ca permet de limiter le nombre d'acces.

    mutex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MyMutex := OpenMutex(nil, false, 'Nom du mutex');
    if MyMutex = nil then
      MyMutex := CreateMutex(nil, false, 'Nom du mutex');
    WaitForSingleObject(MyMutex, TpsEnMillisecondes);
    //traitement
    ReleaseMutex(MyMutex);
    Le principe du Mutex est d'avoir 2 positions : une valide et l'autre non.
    Je pense que c'est ce qui te convient le mieux.

    "Operation atomique":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if GlobalFindAtom('Nom de ton atome') = 0 then
       MyAtom := GlobalAddAtom('Nom de ton atome')
    //Traitement
    GlobalDeleteAtom('Nom de ton atome');
    Bien sur, il est conseille de placer de genre de code dans des blocs try except finally.

  10. #10
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Points : 107
    Points
    107
    Par défaut
    Et de quel type est MyMutex alors?

  11. #11
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Points : 485
    Points
    485
    Par défaut
    Faut appuyer sur F1 des fois quand meme

    The OpenMutex function opens an existing named mutex object.

    HANDLE OpenMutex(
    DWORD dwDesiredAccess,
    BOOL bInheritHandle,
    LPCTSTR lpName
    );

    Return Values
    If the function succeeds, the return value is a handle to the mutex object.

    If the function fails, the return value is NULL. To get extended error information, call GetLastError.

    If a named mutex does not exist, the function returns ERROR_FILE_NOT_FOUND.

  12. #12
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Il y a peut être plus simple en gérant des transactions directement avec la base de données, si, bien sûr la base gère les transactions.

    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
     
    BeginTrans
    try
      Select ...
      Vérification ...
      si c'est ok alors
      debut
        Insert ...
        Commit
      fin
      sinon
        Rollback
    Exception
      RollBack
    end;
    si une demande de transaction est faite pendant la première la seconde devra attendre que la première finisse.
    Si une erreur intervient lors d'une transaction , cette derniere est annulée.

    Bon tutorial sur les transactions

  13. #13
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Points : 107
    Points
    107
    Par défaut
    Oui pour l'instant je l ai fait avec les transactions mais j aimerais qd meme bien réussir aussi avec les Mutex ... Par contre je ne trouve toujours pas la librairie à inclure pour pouvoir faire le OpenMutex!
    Sinon, tu n'aurais pas un exemple fonctionnel???

  14. #14
    Membre confirmé

    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 41
    Points : 485
    Points
    485
    Par défaut
    La declaration d'importation est dans l'unit Windows, il suffit donc de l'inclure dans les uses.
    Maintenant, j'ai lu que tu avais D8, est ce que D8 ne fait que du .net ??

    Sinon, je pense que tu peux importer des fonctions de DLL :
    function OpenMutex(dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PChar): THandle; stdcall;
    function OpenMutexA(dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PAnsiChar): THandle; stdcall;
    function OpenMutexW(dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PWideChar): THandle; stdcall;
    dans kernel32.dll

Discussions similaires

  1. Question Synchronisation Replication
    Par rippoz dans le forum Outils
    Réponses: 4
    Dernier message: 27/11/2007, 16h11
  2. Question synchronisation ?
    Par ®om dans le forum Langage
    Réponses: 7
    Dernier message: 09/09/2006, 16h36
  3. question: Synchronisation de threads
    Par remimichot dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 23/07/2006, 18h27
  4. Question sur la synchronisation
    Par Pépé Lélé dans le forum Langage
    Réponses: 2
    Dernier message: 08/01/2006, 17h46
  5. Question sur la synchronisation des threads.
    Par sebastieng dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 07/12/2005, 15h55

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