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

C++Builder Discussion :

Threads fonction


Sujet :

C++Builder

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 41
    Points : 36
    Points
    36
    Par défaut Threads fonction
    Bonjour à tous

    je suis sous Builder 6.0

    voilà j'aimerais faire une fonction qui ajouterais une ligne dans un fichier pour faire un fichier log mais cette fonction est appellée par plusieurs threads ... esque ca pose un pb si ... il arrivais que 2 threads appele la fonction en meme temps ? ou est ce que je doit l'empecher avec des evenements ou un mutex ? ( la ca a l'air de tourner sans mais bon ... )

    merci d'avance

  2. #2
    Membre averti
    Avatar de Neo41
    Inscrit en
    Janvier 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 241
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    dans ton cas l'utilisation d'une section critique ou d'une mutex est très importante, parce tu risques de te retrouver avec un fichier dont le contenu est le mélange des deux threads (si à un instant X les 2 l'ouvrent en même temps) !

    En règle générale, du moment où une tâche peut être excécutée par plusieurs threads, il faut protéger l'accès par une section critique.
    "Don't think you are, know you are..." (Morpheus)

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 41
    Points : 36
    Points
    36
    Par défaut
    merci de la reponse :

    hmm d'accord ca veut donc dire que une fonction peut etre executé plusieur fois en meme temp par different threads ? donc je peut faire un truc du genre :

    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
    void AddLog(AnsiString Message)
    {
       //Attendre que le Mutex soit Libre
       ...
     
       //Ajout de Message à la fin du fichier
       fstream FichierLog;
     
       FichierLog.open("LogFile.txt",ios_base::out|ios_base::app);
       if (!FichierLog)
       {
          ShowMessage("Impossible d'ouvrir le fichier log");
       }
       else
       {
          Message=AnsiString("\nle "+DateToStr(Date())+" a "+TimeToStr(Time())+" "+Message);
          FichierLog.write(Message.c_str(),Message.Length());
       }
       //Liberer le mutex
       ...
    }
    ?

    et je n'ai pas besoin de le faire a chqque appel de fonction comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       ...
       //Attendre que le Mutex soit Libre
       ...
     
       AddLog("Erreur");
     
       //Liberer le mutex
       ...
    ?

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Exact. Je dirai même que tu dois utiliser du code protégé dans AddLog() et non pas protéger de l'extérieur les appels à AddLog(). Cette deuxième méthode est peu fiable car sensible aux erreurs (aux oublis surtout).

    NB : comme pour tous ce que touche aux allocations/libérations de ressources, il faut être attentif à garantir que toute ressource allouée est libérée. Ici, si tu acquiers un mutex, il faut être absolument sûr que tu le libères avant de quitter la méthode. C'est à dire : avant n'importe quelle instruction return ou malgré n'importe quelle levée d'exception.

    En cas de doute (surtout sur les exceptions), utiliser le principe RAI (resource acquisition is initialization). 8)
    Oups...
    -

  5. #5
    Membre averti
    Avatar de Neo41
    Inscrit en
    Janvier 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 241
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    un conseil concernant l'utilisation des mutex et des sections critiques: Il faut toujours faire le Acquire et le Release dans un bloc Try/finally. Parce que si tu fais un Acquire et qu'après t'as une exception, alors tu vas sortir de la méthode sans avoir relaché la main.Oups...

    Donc en gros:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    try
    {
      SectionCritique->Acquire();
      //Code...
    }
    __finally
    {
      SectionCritique->Release();
    }
    Bon courage
    "Don't think you are, know you are..." (Morpheus)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    41
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 41
    Points : 36
    Points
    36
    Par défaut
    merci pour votre aide je vois ce que j'ai a faire !
    Neo41 :
    Bon courage
    mici !!

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    NB : try / __finally fonctionne bien, mais __finally est une instruction native de Borland. Elle n'existe pas dans la norme du C++.
    Si vous voulez garantir un minimum de portabilité (encore que... une fois sous Borland, si on utilise la VCL, on devient assez peu portable...), utiliser une classe enveloppe (sur le modèle RAI dont je parlais plus haut) est simple et efficace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Mutex; // un mutex quelconque à acquérir/libérer
    class MutexHandler { 
      public : 
      Mutex Handler( Mutex& m ) : m_mutex( m ) 
      { m_mutex.acquire(); }
      virtual ~MutexHandler() 
      { m_mutex.release(); }
      private : 
      Mutex& m_mutex;
    };
    Et comme utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void addLog() {
      ...
      // Tentative d'acquisition 
      MutexHandler mh( *( new Mutex ) );
      // Code éventuellemment susceptible de cacher un return ou une exception
      ...
    }
    L'appel à Mutex::release() se dont fait automatiquement et sans erreur possible en quittant la méthode, quel que soit le point de sortie. 8)
    Oups...
    -

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

Discussions similaires

  1. thread, fonction et mutex ?
    Par AddicTion dans le forum Débuter
    Réponses: 2
    Dernier message: 06/05/2010, 23h08
  2. thread fonction main
    Par ouiouioui dans le forum Langage
    Réponses: 3
    Dernier message: 29/01/2009, 15h00
  3. Réponses: 6
    Dernier message: 30/09/2005, 00h53
  4. [Threads] Sortir d'une fonction bloquante
    Par guejo dans le forum MFC
    Réponses: 19
    Dernier message: 17/08/2004, 14h12
  5. Thread avec une fonction membre d'une classe
    Par SteelBox dans le forum Windows
    Réponses: 6
    Dernier message: 01/03/2004, 01h15

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