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 :

Problème avec QThread [QThread]


Sujet :

Multithreading

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Par défaut Problème avec QThread
    Bonjour à tous,
    Dans le cadre d'un programme, j'ai besoin d'utiliser QThread pour jouer un son (avec une autre librairie que Qt).
    Mais voilà, lorsque j'appelle une méthode de mon thread, l'application fait une erreur avec 'QObject::killTimers: timers cannot be stopped from another thread'.

    Quelqu'un pourrait m'aider ? Merci d'avance.

    Voici mon code :

    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
     
    /*NOTA: j'ai résumé le code concernant la gestion de la musique par
    un "MusicObject".*/
    #include <QThread>
    //autre includes
     
    class MusicThread: public QThread
    {
        public:
            MusicThread(QObject* parent) : QThread(parent)
            {
                _music = new MusicObject;
                _note = 0;
            }
     
            //c'est lorsque j'appelle cette méthode depuis
            //la fenêtre principal que j'ai une erreur
            void noteOn(int n)
            {
                _note = n;
            }
     
        protected:
            void run()
            {
                while (1)
                {
                    _music->setNote(_note);
                    if (_note != 0)
                        _music->process();
                }
            }
     
        private:
            MusicObject* _music; 
            int _note;
    };

  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.
    Pourquoi il te faut un thread???
    Un timer semblerais pas mal dans ton cas. Ou un simple slot.
    Sinon ton problème viens surement du fait que tu créé _music dans le constructeur et que tu l'utilise dans le run. Hors ces deux portions de code ne sont pas exécuté dans le même thread.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Par défaut
    L'utilisation du thread vient de l'architecture interne de la librairie que j'utilise : il lui faut un rafraîchissement constant.
    Sinon, mon code même modifié de marche toujours pas... Voici mon code quasi complet :

    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
    class MusicThread: pulic QThread
    {
        Q_OBJECT
     
        enum ObjectType
        {
            None = 0, AddObject, DelObject, AddInput, DelInput, AddOutput, DelOutput
        };
     
        public:
            MusicThread(QObject* parent) : QThread(parent)
            {
                _objectType = None;
                _objectToAdd = NULL;
            }
     
            void addObject(MusicObject* object)
            {
                if (isRunning())
                {
                    _objectType = AddObject;
                    _objectToAdd = (void*)object;
                }
                else
                    _objects.append(object);
            }
            //du code assez similaire pour ajouter-retirer des entrées/sorties
     
        protected:
            void run()
            {
                QList<MusicInput*> inputs(_inputs);
                QList<MusicObject*> objects(_objects);
                QList<MusicOutput*> outputs(_outputs);
     
                while(1)
                {
                    if (_objectType != None)
                    {
                        if (_objectType == AddObject)
                            objects.append(static_cast<MusicObject*>(_objectToAdd));
                        //code vérifiant les autres conditions...
                    }
     
                    foreach(MusicInput* in, inputs)
                    {
                        in->Read();
                    }
                    //2 autres foreach pour les objets et les sorties
                }
     
                inputs.clear(); objects.clear(); outputs.clear();
            }
     
        private:
            //attributs...
    };
    Une idée ? Merci d'avance.

  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
    Citation Envoyé par Crabe05 Voir le message
    L'utilisation du thread vient de l'architecture interne de la librairie que j'utilise : il lui faut un rafraîchissement constant.
    Et?
    En quoi un simple timer ne suffit pas?

    Citation Envoyé par Crabe05 Voir le message
    Sinon, mon code même modifié de marche toujours pas... Voici mon code quasi complet :
    ...
    Une idée ? Merci d'avance.
    je dirai la même chose
    Sinon ton problème viens surement du fait que tu créé _music dans le constructeur et que tu l'utilise dans le run. Hors ces deux portions de code ne sont pas exécuté dans le même thread.
    sauf que la je ne sais pas ou sont créé tes objects ici...
    A cela je rajouterais ta manière de rajouter un object qui n'est certainement pas thread safe.

    Un petit lien qui devrais t'intéresser :
    http://qt.developpez.com/faq/?page=T...tenance-thread

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Par défaut
    Moi qui pensais éviter l'erreur avec cette manière d'ajouter des objets !
    Voici comment je procède :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [QApplication] -> crée MainWindow
        -[MainWindow] -> crée un MusicThread thread
                      -> crée un MusicObject obj
                      -> thread->ajoute(obj)
        -[Objet thread] -> met obj dans un attribut _obj
        -[Fonction run] -> met _obj dans un QList local
                        -> pour chaque objet o de QList : o->DoProcess()
    Voilà donc le plan. Est-ce que cela t'aide ?
    En ce qui concerne le FAQ (très bien fait d'ailleurs), j'ai du mal à discerner les différentes affinités entre threads et objets...

    Sinon pour répondre au problème du timer : j'ai déjà essayé d'utiliser un timer sur une application sans GUI : même en mettant la valeur du timer très bas (2 ms), j'obtiens un son qui est loin d'être celui que j'attends...

  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
    Citation Envoyé par Crabe05 Voir le message
    Moi qui pensais éviter l'erreur avec cette manière d'ajouter des objets !
    dans ton cas, il suffit d'utiliser un mutex.

    En ce qui concerne le FAQ (très bien fait d'ailleurs), j'ai du mal à discerner les différentes affinités entre threads et objets...
    Un QObject appartiens au thread qui le créé. Le cas d'un QThread, seule les QObject créé dans le context du run lui appartiens.
    Tu pourrais peut être utiliser movetothread dans ton cas.

    Sinon pour répondre au problème du timer : j'ai déjà essayé d'utiliser un timer sur une application sans GUI : même en mettant la valeur du timer très bas (2 ms), j'obtiens un son qui est loin d'être celui que j'attends...
    Si tu as besoin de précision < 20ms oui faut oublier le timer. Tu as tout à fait raison d'utiliser un thread.

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Par défaut
    ça marche grâce aux mutex !!
    Merci mille fois !

  8. #8
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2008
    Messages
    26 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2008
    Messages : 26 752
    Par défaut
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

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

Discussions similaires

  1. [QThread] Problème avec QTcpSocket et QThread
    Par luffydu22 dans le forum Multithreading
    Réponses: 2
    Dernier message: 13/10/2010, 09h26
  2. [QThread] Problème avec QTimer et QThread
    Par scary dans le forum Multithreading
    Réponses: 7
    Dernier message: 15/12/2009, 18h00
  3. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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