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++ Discussion :

Code non thread-safe


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut Code non thread-safe
    Bonjour,

    AVERTISSEMENT: il y a beaucoup de code. Si vous n'avez pas le temps de trop regarder, ce serait sympa de me dire à quoi peut-être du un seg fault dans une app multithreadée , je me débroullerai avec ça.

    POUR CEUX QUI ONT DU TEMPS:
    Je suis entrain de faire une application capable de crypter/décrypter des messages par courbe elliptique. On m'a conseillé aussi de faire un crackeur par force brute pour montrer que cette méthode de cryptage est par son concept sûre.
    J'ai fait une classe User<T> représentant une personne souhaitant pouvoir envoyer des messages cryptés à un autre User qui le décryptera. J'ai fait une classe Cracker<T> (nom très recherché ) dérivée de User<T> qui elle intercepte les messages des users et tente de les décrypter (le pauvre ne sait pas que c'est dur et long)...
    Le crackeur cherche à trouver une clé secrète d'un des deux user qu'il surveille. Pour ce faire je le dote de 4 threads suplémentaires (je pourrais ajouter des centaines de threads si j'avais une machine avec assez de cores et de processeurs)pour l'aider à trouver plus vite.
    Sauf que mon code plante lamentablement sur un seg fault dès que j'ajoute un crackeur.
    J'ai essayé d'ajouter des blocages/déblocages de mutex un peu partout dans le code qui accède à des membres et je fait des copies de ceux-ci. Mais ça plante toujours.
    J'ai jamais réellement touché aux threads avant ce projet donc je sais pas quoi faire. Le debugueur de VS ne m'est pas super utile en plus (il me repère juste le seg fault mais ne me dit pas quel appel l'a provoqué dans quel thread).

    J'ai fait mes propres classes de thread et de mutex (c'est un impératif) donc le problème vient peut-être de là...

    Mon code:
    ZThread.hpp
    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
     
    #ifndef ZTHREAD_HPP_INCLUDED
    #define ZTHREAD_HPP_INCLUDED
     
    #include <windows.h>
     
    unsigned __stdcall launcherfunc(void* data);
     
    class ZThread
    {
            friend unsigned __stdcall launcherfunc(void* data);
     
        public:
     
            ZThread();
            ZThread(void* (*ptrFunc)(void*),void* data=NULL);
     
            virtual ~ZThread();
     
            void Start();
            void Wait();
            void Terminate();
     
            bool IsRunning(){return m_isRunning;}
            void* GetReturnedValue(){return m_returnedValue;}
     
        protected:
     
            virtual void* Run();
     
            HANDLE m_handle;
            unsigned m_id;
     
            void* m_data;
            void* (*m_ptrFunc)(void*);
     
            bool m_isRunning;
     
            void* m_returnedValue;
    };
     
    #endif // ZTHREAD_HPP_INCLUDED
    ZThread.cpp
    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
    55
    56
    57
    58
    59
    60
    61
     
    #include "ZThread.hpp"
    #include <process.h>
    #include <iostream>
     
    unsigned __stdcall launcherfunc(void* data)
    {
        ZThread* tmpInstance=static_cast<ZThread*>(data);
        tmpInstance->m_isRunning=true;
        tmpInstance->m_returnedValue=tmpInstance->Run();
        tmpInstance->m_isRunning=false;
        _endthreadex(0);
        return 0;
    }
     
    ZThread::ZThread(): m_handle(NULL),
     m_ptrFunc(NULL),
     m_data(NULL),
     m_isRunning(false),
     m_returnedValue(NULL)
    {
    }
     
    ZThread::ZThread(void* (*ptrFunc)(void*), void* data):
     m_handle(NULL),
     m_ptrFunc(ptrFunc),
     m_data(data),
     m_isRunning(false),
     m_returnedValue()
    {
    }
     
    ZThread::~ZThread()
    {
        if(m_isRunning)
            Wait();
    }
     
    void*  ZThread::Run()
    {
        if(m_ptrFunc!=NULL)
            return m_ptrFunc(m_data);
        return (void*) 0;
    }
     
    void ZThread::Start()
    {
        m_handle=(HANDLE)_beginthreadex(NULL,0,&launcherfunc,this, 0,&m_id);
        if(m_handle==NULL)
            throw("Unable to create a new thread");
    }
     
    void ZThread::Wait()
    {
        if(m_isRunning)
        {
            WaitForSingleObject(m_handle,INFINITE);
            CloseHandle(m_handle);
            m_handle=NULL;
        }
    }
    ZMutex.hpp
    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
     
    #ifndef ZMUTEX_HPP_INCLUDED
    #define ZMUTEX_HPP_INCLUDED
     
    #include <windows.h>
     
    class ZMutex
    {
        public:
     
            ZMutex();
            ~ZMutex();
     
            void Lock();
            void UnLock();
            bool IsLocked(){return m_isLocked;}
     
        protected:
     
            CRITICAL_SECTION m_mutex;
            bool m_isLocked;
    };
     
    #endif // ZMUTEX_HPP_INCLUDED
    ZMutex.cpp
    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
     
    #include "ZMutex.hpp"
     
    ZMutex::ZMutex():
     m_isLocked(false)
    {
        InitializeCriticalSection(&m_mutex);
    }
     
    ZMutex::~ZMutex()
    {
        DeleteCriticalSection(&m_mutex);
    }
     
     
    void ZMutex::Lock()
    {
        if(!m_isLocked)
        {
            m_isLocked=true;
            EnterCriticalSection(&m_mutex);
        }
    }
     
    void ZMutex::UnLock()
    {
        if(m_isLocked)
        {
            LeaveCriticalSection(&m_mutex);
            m_isLocked=false;
        }
    }
    User.hpp
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
     
    #ifndef USER_HPP_INCLUDED
    #define USER_HPP_INCLUDED
     
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <map>
    #include "ZMutex.hpp"
     
    #include "EllipticCurveUT.hpp"
     
    template<typename T>
    class Connection
    {
        public:
     
            Connection(){}
            Connection(std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve,std::pair<T,T> refPoint):
             m_correspondanceTable(correspondanceTable),
             m_curve(curve),
             m_refPoint(refPoint)
             {}
     
        std::multimap<char, std::pair<T,T> > m_correspondanceTable;
        EllipticCurve<T> m_curve;
        std::pair<T,T> m_refPoint;
        std::pair<T,T> m_firstPoint;
        std::pair<T,T> m_secondPoint;
    };
     
    template<typename T>
    class User
    {
     
    public:
     
        User()
        {
            m_key = 1;//c'est pour voir si le crackage marche
        }
     
        static void EstablishConnection(User* firstUser, User* secondUser, std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve, std::pair<T,T> refPoint)
        {
            firstUser->EstablishConnection(secondUser, correspondanceTable, curve, refPoint);
            secondUser->EstablishConnection(firstUser, correspondanceTable, curve, refPoint);
            firstUser->EstablishConnection(secondUser, correspondanceTable, curve, refPoint, true);
            secondUser->EstablishConnection(firstUser, correspondanceTable, curve, refPoint, true);
        }
     
        void EstablishConnection(User* beConnectedTo, std::multimap<char, std::pair<T,T> > correspondanceTable, EllipticCurve<T> curve, std::pair<T,T> refPoint, bool secondPart = false)
        {
            m_mutex.Lock();
            if(!secondPart){
                m_connections[beConnectedTo] = Connection<T>(correspondanceTable, curve, refPoint);
                m_connections[beConnectedTo].m_firstPoint = curve.QuickExponentiation(m_key, refPoint);
            }if(secondPart){
                m_connections[beConnectedTo].m_secondPoint = m_connections[beConnectedTo].m_curve.QuickExponentiation(m_key, beConnectedTo->GetComputedPoint(this));
            }
            m_mutex.UnLock();
        }
     
        Connection<T> GetConnection(User* user){m_mutex.Lock(); return m_connections[user]; m_mutex.UnLock();}
     
        std::pair<T,T> GetComputedPoint(User* connectedTo){m_mutex.Lock(); return m_connections[connectedTo].m_firstPoint; m_mutex.UnLock();}
     
        std::vector<std::pair<T,T> > CryptMessage(User* receiver, std::string message)
        {
            m_mutex.Lock();
            std::vector<std::pair<T,T> > cryptedMessage;
            cryptedMessage.push_back(m_connections[receiver].m_firstPoint);
     
            std::multimap<char, std::pair<T,T> > correspondanceTable = m_connections[receiver].m_correspondanceTable;
            m_mutex.UnLock();
     
            typename std::multimap<char, std::pair<T,T> >::iterator iter;
            for(unsigned int i =0; i < message.length(); i++)
            {
                iter = correspondanceTable.find(message[i]);
     
                if( iter != correspondanceTable.end())
                {
                    m_mutex.Lock();
                    cryptedMessage.push_back(m_connections[receiver].m_curve.AddPoints(m_connections[receiver].m_secondPoint, iter->second));
                    m_mutex.UnLock();
                }
                //!TODO: gérer le cas où le caractère est absent de la table
            }
     
            return cryptedMessage;
        }
     
        std::string DecryptMessage(User* sender, std::vector<std::pair<T,T> > message)
        {
            std::string decryptedMessage;
            m_mutex.Lock();
            std::multimap<char, std::pair<T,T> > correspondanceTable = m_connections[sender].m_correspondanceTable;
            m_mutex.UnLock();
     
            typename std::multimap<char, std::pair<T,T> >::iterator iter;
            std::pair<T,T> decryptedPoint;
            for(unsigned int i = 0; i < message.size(); i++)
            {
                m_mutex.Lock();
                decryptedPoint = m_connections[sender].m_curve.SoustractPoints(message[i], m_connections[sender].m_secondPoint);
                m_mutex.UnLock();
                for(iter = correspondanceTable.begin(); iter != correspondanceTable.end(); iter++)
                {
                    if(iter->second == decryptedPoint)
                    {
                        char car[2];
                        car[0] = iter->first;
                        car[1] = '\0';
                        decryptedMessage = decryptedMessage + car;
                        break;
                    }
                }
            }
     
            return decryptedMessage;
        }
     
        void sendMessage(User* receiver, std::string message)
        {
            sendCryptedMessage(receiver, CryptMessage(receiver, message));
        }
     
        void sendCryptedMessage(User* receiver, std::vector<std::pair<T,T> > cryptedMessage)
        {
            receiver->receiveCryptedMessage(this, cryptedMessage);
        }
     
        void receiveCryptedMessage(User* sender,  std::vector<std::pair<T,T> > cryptedMessage)
        {
            std::cout<<"Received message :"<<DecryptMessage(sender, cryptedMessage)<<std::endl;
        }
     
        std::map<User*, Connection<T> > m_connections;
     
        static ZMutex m_mutex;
     
    protected:
     
        long long m_key;
    };
     
    template<typename T>
    ZMutex User<T>::m_mutex;
     
    #endif // USER_HPP_INCLUDED
    Cracker.hpp
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
     
    #ifndef CRACKER_HPP_INCLUDED
    #define CRACKER_HPP_INCLUDED
     
    #include <iostream>
    #include "User.hpp"
    #include "ZMutex.hpp"
    #include "ZThread.hpp"
     
    template<typename T>
    class Cracker;
     
    template<typename T>
    class InfoPackage
    {
        public:
     
            InfoPackage(){}
            InfoPackage(Cracker<T>* cracker, User<T>* user, User<T>* connectedUser, int offset, int iterateBy):
             m_cracker(cracker),
             m_user(user),
             m_connectedUser(connectedUser),
             m_offset(offset),
             m_iterateBy(iterateBy)
            {}
     
            InfoPackage(const InfoPackage<T>& rhs)
            {
                m_cracker = rhs.m_cracker;
                m_user = rhs.m_user;
                m_connectedUser = rhs.m_connectedUser;
                m_offset = m_offset;
                m_iterateBy = rhs.m_iterateBy;
            }
     
            Cracker<T>* m_cracker;
            User<T>* m_user;
            User<T>* m_connectedUser;
            int m_offset;
            int m_iterateBy;
    };
     
    template<typename T>
    void* CrackKey(void* infos)
    {
        InfoPackage<T> informations = *(static_cast<InfoPackage<T>*>(infos));
        Cracker<T>* cracker = informations.m_cracker;
        cracker->m_mutex.Lock();
        std::pair<T,T> point = cracker->m_connections[informations.m_user].m_refPoint;
        std::pair<T,T> researchedPoint = informations.m_user->GetComputedPoint(informations.m_connectedUser);
        EllipticCurve<T> curve = cracker->m_connections[informations.m_user].m_curve;
        cracker->m_mutex.UnLock();
     
        for(long long i = informations.m_offset + 1;; i+= informations.m_iterateBy)
        {
            cracker->m_mutex.Lock();
            if(cracker->keyA != 0)
                break;
     
            if(curve.QuickExponentiation(i, point) == researchedPoint)
            {
                cracker->keyA = i;
                std::cout<<"KeyA found: "<<i<<std::endl;
                break;
            }
            cracker->m_mutex.UnLock();
        }
        cracker->m_mutex.UnLock();
        return (void*)1;
    }
     
    template<typename T>
    class Cracker: public User<T>
    {
        public:
     
            Cracker():
             keyA(0),
             keyB(0)
            {
            }
     
            void EstablishConnection(User<T>* firstUser, User<T>* secondUser)
            {
                this->m_connections[firstUser] = firstUser->GetConnection(secondUser);
                CrackKeys(firstUser, secondUser);
            }
     
            void CrackKeys(User<T>* firstUser, User<T>* secondUser)
            {
                InfoPackage<T> infos(this, firstUser, secondUser, 0, 4);
                firstThread = new ZThread(&CrackKey<T>, (void*)&infos);
                firstThread->Start();
                infos.m_offset = 1;
                secondThread = new ZThread(&CrackKey<T>, (void*)&infos);
                secondThread->Start();
                infos.m_offset = 2;
                thirdThread = new ZThread(&CrackKey<T>, (void*)&infos);
                thirdThread->Start();
                infos.m_offset = 3;
                fourthThread = new ZThread(&CrackKey<T>, (void*)&infos);
                fourthThread->Start();
            }
     
     
            std::string DecryptMessage(User<T>* sender, std::vector<std::pair<T,T> > message)
            {
            }
     
            void Wait()
            {
                firstThread->Wait();
                secondThread->Wait();
                thirdThread->Wait();
                fourthThread->Wait();
            }
     
        long long keyA;
        long long keyB;
     
        protected:
     
        ZThread* firstThread;
        ZThread* secondThread;
        ZThread* thirdThread;
        ZThread* fourthThread;
    };
    voilà.
    Merci pour votre aide.

  2. #2
    screetch
    Invité(e)
    Par défaut
    il manque le main dfficile dans tant de code de s'y retrouver

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Je peux résumer le main à ça (il est assez long):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int main(int argc, char** argv)
    {
        User<long long> bob, alice;
        User<long long>::EstablishConnection(&bob, &alice, correspondancesTable, curve, GetAzardousPoint(points));//table de correspondance caractère/point, courbe utilisée, point de référence
        Cracker<long long> oscar;
        oscar.EstablishConnection(&bob, &alice);
     
        bob.sendMessage(&alice, "BONJOUR");
     
        oscar.Wait();
    }

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Bon en fait, ça ne marchait pas parceque le pointeur sur mon InfoPackage ne pointait plus vers une adresse mémoire valide après la fin de la fonction CrackKeys();

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    D'abord, je rappellerais que l'erreur de segmentation a quasi toujours la même origine: on essaye d'accéder à une adresse mémoire qui n'est plus considérée comme valide.

    Ensuite, il faut se rappeler que le principe même du thread est de permettre du travail "concurrent", mais donc que les différents threads sont susceptibles de terminer à des moments différents...

    Ainsi, il se peut très bien le que thread "second" finisse son travail avant les threads first, third et fourth, et que tu devrait veiller à pouvoir gérer cela de manière sécurisante pour toi.

    Enfin, j'ai croisé quelques new qui n'ont pas leur delete équivalent...

    Avant de te lancer dans les threads, tu devrait déjà sans doute essayer d'éviter les fuites mémoire de ce type, et, comme de nombreux membres sont des pointeurs, je te conseillerais de les initialiser à NULL au départ, et de les refaire pointer sur NULL dés que l'adresse sur laquelle ils pointent devient invalide.

    De cette manière, il te sera plus facile de tester si chacun de tes pointeurs est valide, et de ne lancer un traitement que si c'est effectivement le cas.

    toutes ces remarques devraient déjà te permettre d'éviter pas mal d'erreurs de segmentation, même si je ne suis pas (loin s'en faut) un spécialiste des threads
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Je savais à quoi est dû une erreur de segmentation mais je ne voyais pas d'où elle provenait: elle était sous mes yeux et je cherchait ailleurs
    J'ai enlevé une partie du code dont le destructeur, qui fait pas mal de choses dont les dé-allocations.
    Merci pour les conseil toujours bons à respecter

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ta classe de mutex n'est pas bonne. Elle ne devrait pas mémoriser le fait d'être verrouillée ou non, ce n'est pas son rôle (si tu veux une fonction qui retourne immédiatement si elle ne peut pas verrouiller, tu dois implémenté un vrai TryLock() qui retourne une valeur pour indiquer le succès ou l'échec du verrouillage. Et dans celui-ci, appeler directement TryEnterCriticalSection() sans t'embarrasser d'une variable supplémentaire).

    Par contre, tu peux mémoriser l'id du thread qui possède le lock si tu veux empêcher les verrouillages récursifs...

    Et tu peux aussi te faire une classe VerrouMutex qui serait utilisée en RAII sur la classe de Mutex...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Ah, ok.
    Les mutex win sont donc récursifs?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Il me semble bien que mutexes ET sections critiques sont récursifs.
    Mais ton code n'empêchait pas ça. Il niait tout simplement l'utilité du mutex puisqu'il supprimait l'appel à la fonction d'attente si le mutex est pris...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 217
    Par défaut
    Je vais changer tout ça, j'ai trouvé le coin où se trouve la doc' des mutexes threads sur msdn-en

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

Discussions similaires

  1. [MultiThreading] DecimalFormat.parse non thread-safe
    Par Jidefix dans le forum Concurrence et multi-thread
    Réponses: 9
    Dernier message: 06/05/2009, 16h17
  2. [RCP] Treeviewer non thread-safe ?
    Par Guildux dans le forum Eclipse Platform
    Réponses: 4
    Dernier message: 09/01/2007, 13h00
  3. [Composant] Comment déclarer un code thread safe ?
    Par AiSpirit dans le forum Framework .NET
    Réponses: 5
    Dernier message: 26/08/2006, 11h37
  4. Code "Thread Safe" ?
    Par Neitsa dans le forum C++
    Réponses: 3
    Dernier message: 23/12/2005, 14h33
  5. [MFC] CMAP non thread safe ?
    Par fmarot dans le forum MFC
    Réponses: 5
    Dernier message: 04/10/2005, 13h21

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