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

WinDev Discussion :

Limiter l'exécution simultanée d'un Code


Sujet :

WinDev

  1. #1
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut Limiter l'exécution simultanée d'un Code
    Bonjour,
    Dans une application pouvant être exécutée à plusieurs instances en même temps, je souhaiterai limiter l'exécution d'un traitement (clique sur bouton Valider) à un seul utilisateur au maximum en même temps.

    à titre d'information, le traitement de la "section critique" en question concerne l'ajout d'enregistrement à un fichier et l'envoi de mail.

    Pour cela, je compte utiliser une sorte de sémaphore de la manière suivante :
    Je stocke dans un fichier un drapeau qui indique si la section critique est actuellement en cours d'exécution ou non.
    Lorsque un utilisateur clique sur le bouton Valider, on teste d'abord la valeur du drapeau :
    s'il est à 1 (ce qui signifie la Section critique est en cours d'exécution par un autre user), alors patienter et refaire le teste.
    Sinon (Section Critique libre), on met l'indicateur à 1 (afin d'empêcher d'autres user d'y rentrer), on exécute le traitement puis on remet l'indicateur à 0 pour libérer la section critique :

    En gros le code ressemble à quelque chose comme ça :
    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
     
    Drapeau = LireDrapeau() // Lire le contenu du fichier et mettre l'indicateur dans la variable drapeau
    TANTQUE nDrapeau=1
    	Temporisation(100);
    	Drapeau = LireDrapeau(); // Lire le contenu du fichier et mettre l'indicateur dans la variable drapeau
    FIN
    //Section Critique Libre
    Drapeau = 1; // bloquer la section critique
    EcrireDrapeau(); // Ecrire le contenu de la variable dans le fichier
     
    //DEBUT SECTION CRITIQUE
    ...
    //FIN SECTION CRITIQUE
     
    Drapeau=0;
    EcrireDrapeau();//Remettre l'indicateur à 0.


    Théoriquement, cela doit fonctionner, mais en pratique (Windev). Est-ce que cette méthode peut poser problème dans certains cas??

    L'utilisation des Sémaphores permet justement de palier à ce problème, mais j'ai cru comprendre que cela concerne les spécialement threads alors que dans mon cas il s'agit d'un programme exécuté à plusieurs instances en même temps.
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Je ne connais pas ta procédure EcrireDrapeau, mais je vois ici un problème: si 2 instances démarrent en même temps, les deux vont mettre à 1 le drapeau.
    Une des deux va réussir, et continuer le code, et la deuxième va aussi continuer, bien qu'elle n'aura pas eut le drapeau.

    Si toutes les instances doivent tourner sur la même machine, les sémaphores sont parfaites (c'est d'ailleurs expliqué dans l'aide).

    Sinon il faut que ton code vérifie si c'est bien l'instance courante qui a posé le verrou.
    Il faut aussi prévoir une méthode pour supprimer le verrou à la main, en cas de plantage de l'application pendant le traitement.

    Tatayo.

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 278
    Points : 2 151
    Points
    2 151
    Par défaut
    Je pense que ce que vous imaginez fonctionnera. Il faut juste prévoir un déverrouillage en cas de plantage du soft....
    SQL : le véritable Esperanto

    "Les patates à ta tata épatent ton tonton mais les pates aux thons à ton tonton épatent pas ta tata." (Michel Souris)

    MERCI DE NE PAS M'ENVOYER DE MESSAGE PRIVE POUR DES QUESTIONS TECHNIQUES SANS MON ACCORD !

  4. #4
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut
    Je vous remercie pour vos réponses !

    Il est vrai que j'ai négligé le fait que deux instances puissent démarrer au même instant.
    Cependant en terme de probabilité,pensez vous qu'il soit nécessaire de traiter ce cas étant donnée que le nombre d'utilisateurs ne dépasse pas 5 en même temps, de plus le clique sur le bouton Valider ne peut se faire qu'une seule fois durant toute l'exécution.

    Aussi, vous avez tout à fait raison concernant le mécanisme de déverrouillage en cas de plantage. Je vais tenter d'y remédier.

    Merci encore une fois.
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  5. #5
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 278
    Points : 2 151
    Points
    2 151
    Par défaut
    J'ai cru qu'il s'agissait d'une application monoposte... mais s'il peut y avoir 5 utilisateurs, selon la loi de Murphy, ils vont cliquer tous les 5 en même temps.
    SQL : le véritable Esperanto

    "Les patates à ta tata épatent ton tonton mais les pates aux thons à ton tonton épatent pas ta tata." (Michel Souris)

    MERCI DE NE PAS M'ENVOYER DE MESSAGE PRIVE POUR DES QUESTIONS TECHNIQUES SANS MON ACCORD !

  6. #6
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut
    Vous avez tout a fait raison, même si cela est improbable il faut quand même traiter ce cas !
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  7. #7
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 054
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 054
    Points : 9 394
    Points
    9 394
    Par défaut
    Dans le code que tu proposes, la fonction drapeau() renvoie 0 ou 1.
    Pour sécuriser cela, il ne faut pas écrire 1, mais une chaine parfaitement identifiable ( basée sur un Identifiant de session ?).
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  8. #8
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut
    Si alors au lieu d'écrire la valeur 1 sur le drapeau je met l'identifiant unique de l'utilisateur en cours.
    Puis je libère la section critique après son exécution en mettant le drapeau à 0.

    là je constate que même l’écriture sur le drapeau devient une sectione critique ?!

    Je ne vois pas comment mettre cela en place ?
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    En fait tu peux faire autrement (mais à tester): tu ouvres simplement le fichier en début de traitement, en le bloquant en lecture/écriture, et tu le refermes à la fin du traitement.
    Comme l'ouverture est bloquante, tu ne peux pas avoir 2 utilisateurs qui l'ont ouvert en même temps.
    Le contenu du fichier importe peu, seul compte son ouverture et sa fermeture.
    Enfin en cas de plantage, le fichier est fermé automatiquement.

    Par contre il ne semble pas possible de régler le temps d'attente avec fOuvre()...

    Tatayo.

  10. #10
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2013
    Messages : 12
    Points : 18
    Points
    18
    Par défaut
    Salut b_reda31,

    Ton idée d'utiliser les sémaphores était la bonne, tu aurais du creuser dans ce sens.
    Cette fonction s'utilise effectivement avec des thread, mais il faut savoir que de base quand ton application se lance elle l'est dans le threadPrincipal.
    Ici dans ton cas un Mutex serait suffisant, la seul différence avec le sémaphore est que le Mutex ne permet qu'à un seul thread d’accéder simultanément au code protégé.

    Code windev : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Création du Mutex "MonMutex"
    MutexCrée("MonMutex" , Faux , partageGlobal)
     
    // Balisage du code à protéger
    MutexDébut("MonMutex")
       // ...
       // Mon code
       // ...
    MutexFin("MonMutex")

    Et voilà

  11. #11
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut
    Tout d'abord un Grand Merci à vous deux pour vos pistes !
    Citation Envoyé par vouilloz_d Voir le message
    Salut b_reda31,

    Ici dans ton cas un Mutex serait suffisant, la seul différence avec le sémaphore est que le Mutex ne permet qu'à un seul thread d’accéder simultanément au code protégé.
    Je n'ai en effet pas assez creusé du coté des sémaphores comme vous dites vouilloz. L'utilisation des Mutex me semble aussi très intéressante dans ce contexte, seulement il y a certaines contraintes ; selon l'aide de la fonction mutexcrée le paramètre optionnel "Option" peut prendre une des trois valeurs

    partageAucun Le mutex est propre à l'application. Si la fonction MutexDétruit n'est pas appelée, le mutex est détruit à la fin de l'application.
    partageGlobal Le mutex est partagé avec toutes les applications de la machine.
    partageUtilisateur Le mutex est partagé avec toutes les applications de la session de l'utilisateur qui exécute l'application.
    Le client demande à ce que l'application puisse fonctionner sur un seul poste avec plusieurs instances (en même temps), chaque utilisateur se connecte à la machine à travers un logiciel de contrôle à distance et exécute le programme sur sa propre session utilisateur Windows. Jusqu'ici pas de problème.
    Mais une partie de mon application est exécuté depuis une autre machine connecté en réseau local et accède aussi à cette section critique qui pose problème.
    Donc pour résumer, on a du plusieurs instances sur le même poste et une seule instance sur un autre poste, les deux poste partagent la même base de données.
    L'utilisation de Mutex n'est donc malheureusement pas possible dans ce cas (multi-postes).



    Citation Envoyé par tatayo Voir le message
    En fait tu peux faire autrement (mais à tester): tu ouvres simplement le fichier en début de traitement, en le bloquant en lecture/écriture, et tu le refermes à la fin du traitement.
    Comme l'ouverture est bloquante, tu ne peux pas avoir 2 utilisateurs qui l'ont ouvert en même temps.
    Le contenu du fichier importe peu, seul compte son ouverture et sa fermeture.
    Enfin en cas de plantage, le fichier est fermé automatiquement.

    Par contre il ne semble pas possible de régler le temps d'attente avec fOuvre()...

    Tatayo.
    Je viens de tester sur un seul poste, et ça a l'air de fonctionner,Merciii j'ai procédé comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    n est un entier;
    n = fOuvre(fRepDonnées()+"\test.txt",foBloqueEcriture);
     
    TANTQUE n=-1
    	Temporisation(100);
    	n = fOuvre(fRepDonnées()+"\test.txt",foBloqueEcriture);
    FIN
    Info("debut section critique");
    ......
    Info("Fin section critique");
    fFerme(n);
    Est-ce bon ?
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  12. #12
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 054
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 054
    Points : 9 394
    Points
    9 394
    Par défaut
    Je découvre les fonctions Mutex(), mais à priori, les fonctions Mutex() sont parfaites en mono-poste.
    Ici, on a différents utilisateurs qui partagent une même base de donnée.
    Ca marche aussi dans ce cas ?
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  13. #13
    Membre éprouvé Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Points : 961
    Points
    961
    Par défaut
    Non malheureusement, dans mon cas il y a deux postes qui partagent la même base de données et un des deux poste exécute plusieurs instances de l'application
    « Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste!!»

  14. #14
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 278
    Points : 2 151
    Points
    2 151
    Par défaut
    Me vient une idée... plutôt qu'un fichier je vous suggère d'utiliser le SGBD pour gérer votre verrou.
    Ceci afin de gérer l'accès concurrentiel sans trop de prise de tête....
    SQL : le véritable Esperanto

    "Les patates à ta tata épatent ton tonton mais les pates aux thons à ton tonton épatent pas ta tata." (Michel Souris)

    MERCI DE NE PAS M'ENVOYER DE MESSAGE PRIVE POUR DES QUESTIONS TECHNIQUES SANS MON ACCORD !

Discussions similaires

  1. Réponses: 12
    Dernier message: 21/12/2006, 11h49
  2. Réponses: 7
    Dernier message: 11/09/2006, 14h23
  3. Une seule exécution simultanée
    Par vertical dans le forum Général Python
    Réponses: 6
    Dernier message: 21/05/2006, 14h56
  4. Réponses: 4
    Dernier message: 01/02/2006, 14h56
  5. Exécuter simultanément plusieurs fonctions
    Par benj63 dans le forum C++Builder
    Réponses: 5
    Dernier message: 05/10/2005, 16h42

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