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

Multithreading Discussion :

Morceau d'interface dans un thread ?


Sujet :

Multithreading

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut Morceau d'interface dans un thread ?
    Bonsoir,

    Je suis en train de réaliser une interface graphique pour un système de 2 caméras. Récément j'ai du rajouter du multitheading au programme afin que l'interface ne gèle pas pendant l'acquisition. A l'heure actuelle, mon programme se compose d'une thread principale mère contenant toute l'ihm (zones d'affichage des caméras incluses) et d'une ou deux threads fille (selon le nombre de caméra en fonctionnement) appelées lors du click sur le bouton start. Les thread filles consistent en une boucle (pseudo-infini) dans laquelle elles récupèrent la dernière image acquise et la transmete à leur zone d'affichage respective via un signal. Le programme marche trés bien pour chaque cméra séparemen mais quand les deux caméras fonctionne en même temps le programme plante?!! Je me dit que c'est peut être du à l'émission simultanée des deux signaux vers la thread mère (ie leur zone d'affichage).
    Du coup je pensais remédier à ce problème en créant les zones d'affichage dans une thread qui leur est propre mais je sais pas si c'ets possible... d'autant plus que je voudrais que les zones d'affichages restent dans la fenêtre principale.
    Merci d'avance.

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut,
    Ce que tu fait me semble correcte.
    Que te dit le debuggeur?
    Peut tu mettre un peu de code?
    Qu'envoie tu pas le signal?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    le signal transmets une QImage, bien entendu j'ai utilisé qResgisterMetatype avant l'envoie, comme dans le tuto mandlebrot sur Qt .

    Sinon voila le code du run :
    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
    void getImage::run (){
    	status = 20072;
    	QImage image(resX, resY, QImage::Format_RGB16);
    	while (status == 20072){
    			SetCurrentCamera(handle);
    				//attente et acquisition de la dernière image
                                    erreur = WaitForAcquisitionByHandle(handle);
    				erreur = GetMostRecentImage(imData, resX*resY);
    				emit msg(erreur);
                                    //construction de la QImage point par point
    				if (erreur == 20002){
    					for (int i = 0 ; i<resX ; ++i ){
    						for (int j = 0; j<resY ; ++j){
    							image.setPixel(i, j, qRgb(imData[j*resX+i], imData[j*resX+i], imData[(j)*resX+i]));
    						}
    					}
    				}
    				emit hotImage (image);
    			SetCurrentCamera(handle);
    			GetStatus(&status);
    			}
     
    }
    et

    voici la partie qui reçoit et affiche l'image

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void GLDisplay::newImage(QImage im){
    	display->setPixmap(QPixmap::fromImage(im));
    }
    les image font 658*496 pixels, 16 bit par pixels soit approximativement 5.2 mo par image (si je ne trompe pas), à 30 ips par caméra... Peut être la l'afflux de données est trop important?

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Ce que tu as fait est bien.

    Ou créé tu les handel?

    Tu devrai optimizer cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    for (int i = 0 ; i<resX ; ++i )
    {
        for (int j = 0; j<resY ; ++j)
        {
            image.setPixel(i, j, qRgb(imData[j*resX+i], imData[j*resX+i], imData[(j)*resX+i]));
        }
    }
    1- il faut parcourire l'image ligne par ligne que colone par colone, ca fait moins de chargement/déchargement mémoire
    2-setpixel est très lent. Si possible, il faut mieux aller taper la mémoire directement. Tu est sur que t'as caméra fait du RGB16 tel que le défini Qt?
    http://qt.developpez.com/doc/4.6-sna...e/#format-enum

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    merci pour ta réponse

    merci aussi pour le conseil pour la construction de l'image, je corrige ca tout de suite.
    Sinon malheuresement ma caméra m'envoie des images 14bit.... et oui c'est pas le plus pratique . En fait si j'arrive à résoudre le problème de plantage, j'essaierai d'intégrer de l'openGl histoire de pouvoir manipuler plus facilement les images.
    Quand au problème de plantage, j'ai vraiment l'impression que la thread principale est débordée par l'afflux simultané (même si le traitement ne l'est pas)
    de données. Par exemple lorsque les caméra sont synchronisées, le programme plante après la première image afficher...

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    par contre tu n'as pas répondu. Ou créé tu les handel?

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    heu quel handle?

    je sais pas si je réponds à ta question mais j'utilise l'objet getImage pour depuis l'objet GLdiplay (qui n'a de gl que le nom) qui défini la zone d'affichage d'une caméra. Il y a donc deux objets GLdisplay (un par caméra), ils sont tous deux gérés par la thread mère.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SetCurrentCamera(handle);
    //attente et acquisition de la dernière image
     erreur = WaitForAcquisitionByHandle(handle);
    tu utilise un handel pour récuperer une images. Si je ne me trompe pas, les handel ne sont pas thread safe et peuvent être utilisé que par la thread qui le créé. Si, les handel ne sont créé dans le run (ou fonction appelé par le run) tu as des problèmes de concurrence de ressource système. Ainsi, ca tombe en marche avec une caméra et crash avec deux.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    les handles sont acquis dans le thread principal avant la construction des différents object de l'interface via une fonction des camera
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GetCamerahandle (long int tabhandle[nbCamera])
    .
    chaque object possède un long int handle qui est initialisé lors de sa création afin de pouvoir dialoguer avec la caméra qui lui est atribuée.

    exemple pour getImage:
    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
     
    //getImage.h
    #ifndef GETIMAGE_H_
    #define GETIMAGE_H_
    #include <QThread>
    class QPixmap;
    class QImage;
     
    class getImage : public QThread{
     
    	Q_OBJECT
     
    public :
    	getImage (long int cameraHandle, QObject * parent = 0);
    	void run ();
     
    	signals :
    		void msg (unsigned int i);
    		void hotImage (const QPixmap &im);
     
    //public slots :
     
    private :
    		long handle;
    		long int *imData;
    		int resX, resY;
    		unsigned int erreur;
    		int status;
     
    };
     
     
    #endif
     
    //getimage.cpp
    getImage::getImage(long int cameraHandle, QObject *parent) : handle (cameraHandle), QThread (parent){
     
    }
    mais la je comprends pas pourquoi ca planterai, nulle part il y a d'accés sur ce handle(faut que je déclare const d'ailleurrs...:mrgeen à part lors de la contruction.
    du coup je vais tester d'implémenter une fonction getHanlde(long handle) que j'utiliserais dans le run().

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Zhitoune Voir le message
    mais la je comprends pas pourquoi ca planterai, nulle part il y a d'accés sur ce handle(faut que je déclare const d'ailleurrs...:mrgeen à part lors de la contruction.
    Normalement, un handel doit être utiliser par le thread qui le créé. Car son initialisation dépend du thread créateur afin de protéger les accès concurrent au ressources systèmes.
    En tous cas un handle win32 c'est un truc comme cela . Par exemple, c'est pour ce genre de raison que Qt interdit de faire des traitements IHM dans un thread.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    Là par contre je ne crois pas qu'il s'agisse d'un handle win32..

    J'ai modifié le code du run() de la manière suivante :

    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
    void getImage::run (){
    	status = 20072;
    	long camhandle = handle;
    	QPixmap imPix(resX, resY);
    	QImage image(resX, resY, QImage::Format_RGB16);
    	while (status == 20072){
    		SetCurrentCamera(camhandle);
    		//if (status = DRV_ACQUIRING){
    			erreur = WaitForAcquisitionByHandle(camhandle);
    			//emit msg(erreur);//QString::number(erreur)
    			erreur = GetMostRecentImage(imData, resX*resY);
    			emit msg(erreur);
    			if (erreur == 20002){
    				for (int j = 0 ; j<resY ; ++j ){
    					for (int i = 0; i<resX ; ++i){
    						image.setPixel(i, j, qRgb(imData[j*resX+i], imData[j*resX+i], imData[j*resX+i]));
    						//image.setPixel(i, j, qRgb(imData[j*resX+i], imData[j*resX+i], imData[(j)*resX+i]));
    					}
    				}
    			}
    			//emit hotImage (image);
    			imPix = QPixmap::fromImage(image);
    			emit hotImage (imPix);
    			SetCurrentCamera(camhandle);
    			GetStatus(&status);
    			}
     
    }
    mais ca ne marche pas mieux....

    peut être je devrais mettre en place un système pour empêcher l'émission d'une image tant que la précédente n'a pas été affiché?

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long camhandle = handle;
    c'est là qu'il faudrait créé le handel

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    je ne pense pas que qu'il s'agissent d'un déclartion ou d'un handle classique, je dirais plutôt qu'il s'agit du numéro d'ordre de conection des caméras lors de l'initialisation. d'ailleurs il est toujours constant à chaque nouvelle utilisation du programme
    et que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GetNewestImage (100)
    //100 est le "handle" de la première caméra à se connecter
    //201 pour la seconde!
    fonctionne!

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    j'aurais peut êter une piste...
    Est-ce qu'il existe des fonctions permettant de s'assurer qu'un morceau de code au sein d'un thread est éxécuté sans interuption, sans que l'autre thread éxécute un morceau de son code.
    dans mon cas une fois que l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SetCurrentCamera(handle)
    a été éxécutée toutes autre instruction camera doit être éxécutée dans la foulée avant que ne soit éxécutée le setCurrentCamera du thread qui gère l'autre caméra.
    si c'est pas clair j'essaierai de clarifier mieux.

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Zhitoune Voir le message
    j'aurais peut êter une piste...
    Est-ce qu'il existe des fonctions permettant de s'assurer qu'un morceau de code au sein d'un thread est éxécuté sans interuption, sans que l'autre thread éxécute un morceau de son code.
    les mutex
    http://qt.developpez.com/faq/?page=T...pulation-mutex

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    je m'en doutais :o

    merci

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    en fait j'aurai une question : quelle est la portée d'un mutex?
    si j'ai déclarée un mutex dans un objet du thread mère bloque-t'il l'éxécution des autres threads?

  18. #18
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Zhitoune Voir le message
    en fait j'aurai une question : quelle est la portée d'un mutex?
    si j'ai déclarée un mutex dans un objet du thread mère bloque-t'il l'éxécution des autres threads?
    comment cela?

    le mutex est un objet partagé entre plusieurs thread.

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 171
    Par défaut
    j'ai deux instances de GLdisplay qui s'ignore, chacune déclare un QMutex afin de pouvoir protéger l'éxécution de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void GLDisplay::newImage(QPixmap im){//(QImage im){
    	dispMutex.lock();
    	display->setPixmap(im);
    	dispMutex.unlock();
    }
    est-ce que le lock() bloque ici les autres threads?

  20. #20
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par Zhitoune Voir le message
    chacune déclare un QMutex
    faudrait plutôt que ce soit le même non?

Discussions similaires

  1. Réponses: 1
    Dernier message: 01/02/2008, 12h59
  2. Synchronize bloquant dans un thread
    Par bencot dans le forum Langage
    Réponses: 3
    Dernier message: 20/08/2004, 16h42
  3. [Process]Execution de process dans un thread
    Par devjava dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 18/06/2004, 10h34
  4. erreur d'un timer declaré dans un thread
    Par hak5 dans le forum C++Builder
    Réponses: 2
    Dernier message: 03/04/2004, 09h20
  5. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 17h25

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