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 :

[Multi-threading] Connexion impossible ?


Sujet :

C++

  1. #1
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut [Multi-threading] Connexion impossible ?
    Bonjour à tous,

    J'essaye dans mon programme d'accéder à des données sur le réseau intranet de mon entreprise. J'utilise un programme multi-thread, et je me demande si c'est mon programme qui est tout pourri, ou bien si c'est le réseau car ça plante lamentablement...

    Voici mon code simple de test :
    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
    void RequeteServeur()
    {
    	std::cout << "Début du test serveur " << std::endl;
    	std::vector<unsigned short> image(77120);
    	unsigned short* image_ptr = &image[0];
     
    	// On lance 50 fois la boucle
    	for (int i = 500; i != 550; i++)
    	{
    		int cr  = IRimages(36181, 1, i, i, &image_ptr); // Appel serveur
    	}
    	std::cout << "Fin du test serveur " << std::endl;
    }
     
    int main()
    {
    	boost::thread thread1 (&RequeteServeur);
    	boost::thread thread2 (&RequeteServeur);
     
    	thread1.join();
    	thread2.join();
     
    	std::cout << "Appuyez sur entrée pour continuer...";
    	std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    	return 0;
    }
    Alors? C'est moi ou le réseau ?



    EDIT : Quand je dis ça plante, c'est que le débogeur ne me donne pas vraiment d'infos utiles:
    dans vector.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     #endif /* _HAS_ITERATOR_DEBUGGING */
    		_SCL_SECURE_VALIDATE_RANGE(_Pos < size()); // plante ICI
     
    		return (*(_Myfirst + _Pos));
    		}

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Si ça plante c'est que c'est vraisemblablement toi !
    Sans plus d'informations sur ce que fait IRimages c'est dur de savoir où est le problème, juste qu'une tentative d'accès à un élément qui n'existe pas d'un vecteur est faite...
    Tu n'as pas la pile d'appels ?

    MAT.

  3. #3
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    IRimages c'est pas moi qui l'ai codé... ça fait parti des bibliothèques que notre service informatique nous met à disposition.
    C'est une fonction qui va chercher sur le réseau une image, et la stocke dans la case mémoire appropriée...

    Le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        RequeteServeur();
        return 0;
    }
    fonctionne très bien en mono thread. Je récupère tout comme il faut.
    Mais dès que je met deux RequeteServeur en parallèle ça plante, avec un message du style dans la console (cf pièce jointe)
    Images attachées Images attachées  

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Si y'a des données statiques non protégées (en gros que c'est pas prévu pour du multi-thread) dans IRimages, ça va pas être possible de l'utiliser comme ça...

    MAT.

  5. #5
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Bon j'ai envoyé un mail à la personne concernée pour récupérer ce fameux IRImages(). Sinon je vais devoir faire comme j'ai toujours fait: sécuriser le réseau avec un mutex...

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    OK j'ai vu la personne concernée. Le code est vieux de plus de 10 ans, et utilise d'anciennes librairies de décompression JPEG codées par une entreprise sous-traitante...
    Bref, je laisse tomber...

    J'ai plus qu'à créer un singleton Mutex pour sécuriser l'accès réseau et le tour est joué !

  7. #7
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Un singleton c'est peut-être pas obligatoire, mais un wrapper avec un mutex, oui c'est sans doute le plus simple.
    Par contre du coup ça va sérialiser les demandes d'images et si c'est le gros du boulot que réalisent tes threads ça va va pas mal diminuer l'intérêt d'en mettre plusieurs. Mais j'imagine qu'il y a des traitements (coûteux) après de réalisés sur les données de ces images récupérées ?

    MAT.

  8. #8
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Un singleton c'est peut-être pas obligatoire, mais un wrapper avec un mutex, oui c'est sans doute le plus simple.
    Ah? Tu peux m'en dire plus? Qu'entends-tu par wrapper avec un mutex?
    J'ai trouvé un papier intéressant ICI sur Google, mais c'est un mutex wrapper facade.

    Citation Envoyé par Mat007 Voir le message
    Par contre du coup ça va sérialiser les demandes d'images et si c'est le gros du boulot que réalisent tes threads ça va va pas mal diminuer l'intérêt d'en mettre plusieurs. Mais j'imagine qu'il y a des traitements (coûteux) après de réalisés sur les données de ces images récupérées ?
    En fait j'ai pour simplifier des films d'images qui doivent jouer en même temps. C'est pourquoi chaque thread prend en charge de jouer le film avec les traitements appropriés. Donc aller chercher une image sur un serveur n'est qu'une partie de ce que va effectuer chaque thread, effectivement.

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par poukill Voir le message
    Qu'entends-tu par wrapper avec un mutex?
    Bah je pensais juste à une simple classe du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class ImageProvider
    {
      ...
    public:
      int LoadImage( ... )
      {
        boost::mutex::scoped_lock locker( mutex_ );
        return IRimages( ... );
      }
    private:
      boost::mutex mutex_;
    };
    Pas spécialement statique quoi...

    MAT.

  10. #10
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    En fait je pensais ajouter un proxy à mon architecture déjà existante.
    J' ai déjà une classe de base abstraite Camera, dont dérivent un tas de classes concrètes.
    En utilisant le pattern Proxy, j'obtiens:
    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
    class CameraProxy : public Camera {
    public:
    	CameraProxy (Camera * camera) {m_camera = camera;}
    	virtual ~CameraProxy(){}
     
    	virtual vigra::UInt16Image importImage(int numero_image)
    	{
    		// On transmet l'appel en sécurisant le réseau
    		boost::mutex::scoped_lock locker( m_mutex );
    		return m_camera->importImage(numero_image);
    	}
     
    private:
    	Camera * m_camera;
    	boost::mutex m_mutex;
    };
    Le problème ici c'est que le mutex n'est pas unique, c'est pour ça que je proposais de l'encapsuler dans un singleton !

  11. #11
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Mets juste le mutex en membre statique à ce moment-là ?

    MAT.

  12. #12
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Mets juste le mutex en membre statique à ce moment-là ?
    C'est pas faux! Pourquoi se compliquer la vie !

    Merci Mat, tu as de bons conseils comme d'habitude!

    EDIT : le code qui marche
    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
    class Camera
    {
    public:
    	Camera() {}
    	Camera(int num_choc) : m_choc(num_choc){}
    	~Camera(){};
     
    	virtual vigra::UInt16Image importImage(int i) = 0;
     
    protected:
    	int m_choc;
    };
     
    class CameraIR : public Camera
    {
    public:
    	CameraIR(int i): Camera(i) {}
    	CameraIR(): Camera() {}
    	virtual ~CameraIR() {}
     
     
    	virtual vigra::UInt16Image importImage(int i)
    	{
    		std::vector<unsigned short> image(77120);
    		unsigned short* image_ptr = &image[0];		
    		int cr  = IRimages(36181, 1, i, i, &image_ptr); // Appel serveur
     
    		return vigra::UInt16Image(320, 240, &image[0]);
    	}
    };
     
    class CameraProxy : public Camera {
    public:
    	CameraProxy (Camera * camera) {m_camera = camera;}
    	virtual ~CameraProxy(){ delete m_camera; }
     
    	virtual vigra::UInt16Image importImage(int i)
    	{
    		// On transmet l'appel en sécurisant le réseau
    		boost::mutex::scoped_lock locker( m_mutex );
    		return m_camera->importImage(i);
    	}
     
    private:
    	Camera * m_camera;
    	static boost::mutex m_mutex;
    };
     
    boost::mutex CameraProxy::m_mutex;
     
    void RequeteServeur()
    {
    	Camera * camera = new CameraProxy(new CameraIR);
    	vigra::UInt16Image image = camera->importImage(500);
     
            delete camera;
    }
     
    int main()
    {
    	boost::thread thread1 (&RequeteServeur);
    	boost::thread thread2 (&RequeteServeur);
     
    	thread1.join();
    	thread2.join();
     
    	std::cout << "Appuyez sur entrée pour continuer...";
    	std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
    	return 0;
    }

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

Discussions similaires

  1. Lancement de Multi-Threads impossible
    Par Cvanhove dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 09/02/2015, 12h37
  2. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  3. [Multi-thread] Connexion Telnet
    Par max44410 dans le forum Langage
    Réponses: 2
    Dernier message: 08/05/2007, 01h18
  4. Réponses: 1
    Dernier message: 17/11/2006, 23h21
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

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