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

Threads & Processus C++ Discussion :

Le pattern consumer et producer.


Sujet :

Threads & Processus C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Le pattern consumer et producer.
    Salut, je vais tenter d'expliquer mon problème :

    Je possède deux threads, imaginons que le premier soit le CPU et le second le GPU. (Mais ça pourrait être n'importe quoi)
    Ici dans ce cas le GPU joue le rôle de producer et le CPU de consumer.

    Tout deux partagent un buffer, alors le but ça serait que le gpu mette à jour une information quelconque du buffer à l'aide d'un programme (le fragment shader par exemple mais ça pourrait être n'importe quel programme) de manière thread safe sans faire attendre le CPU.

    Voici un pseudo code que j'ai fait qui utilise boost::lockfree.

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    boost::lockfree::queue<int> buffer(128);
    class Producer {
        public :
        void operator()(int v) {
            buffer.push(v);
        }
    };
    Producer p;
    FastDelegate<void> fd(&Producer::operator(), &p, 5);
    buffer.consume_one(fd);
    return 0;

    Alors déjà là j'ai un soucis c'est que je ne peux pas passer un type classe à la queue, sinon ça ne compile pas, il me dit que la classe n'a pas de destructeur trivial, et que je définisse un destructeur ou pas dans la classe ça ne change rien, on dirait que les queues lock free n'acceptent que des variables de type primitif.

    Le problème c'est que je ne peux pas accéder à un élément i du buffer, je suis obligé à chaque fois de push et de pop, donc, je ne sais pas du tout comment faire pour accéder une donnée quelconque de mon buffer et la modifier je pensais faire une classe Task qui contient un std::vector<int> mais comme je ne peux pas utiliser d'autre type que des types primitif..., bref, je ne m'y connais pas beaucoup en programmation multi-threadée et je n'ai pas trouvé beaucoup de doc à se sujet.

    Merci pour votre aide.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    D'après la doc de la bibliothèque, ca accepte les types tels que
    Requirements:
    T must have a copy constructor
    T must have a trivial assignment operator
    T must have a trivial destructor
    Es-tu dans ce cas là?

  3. #3
    Invité
    Invité(e)
    Par défaut
    Salut,

    j'ai essayé de les déclarer :

    Code cpp : 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
     
    class Task {
        public :
        Task() {
            buffer = std::vector<int>(128);
        }
        Task(const Task& task) {
            buffer = task.buffer;
        }
        Task& operator= (const Task& task) {
            buffer = task.buffer;
            return *this;
        }
        void operator()(int index, int value) {
            buffer[index] = value;
        }
        ~Task() {
        }
        private :
            std::vector<int> buffer;
    };
    int main()
    {
        boost::lockfree::queue<Task> tasks(128);
        Task t;
        tasks.push(t);
        FastDelegate<void> command(&Task::operator(), &tasks.pop(), 0, 255);
        tasks.consume_one(command);
        return 0;

    Mais toujours la même erreur de compilation. :/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ||=== Build: Debug in ODFAEG-DEMO (compiler: GNU GCC Compiler) ===|
    /usr/include/boost/lockfree/queue.hpp|81|error: static_assert failed "(boost::has_trivial_destructor<T>::value)"|
    /usr/include/boost/static_assert.hpp|78|note: expanded from macro 'BOOST_STATIC_ASSERT'|
    /home/laurent/Développement/Projets-c++/ODFAEG-DEMO/main.cpp:32:34: note||in instantiation of template class 'boost::lockfree::queue<Task, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>' requested here|
    ||=== Build failed: 1 error(s), 1 warning(s) (0 minute(s), 5 second(s)) ===|

  4. #4
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Laisse le compilateur faire son boulot (génération du constructeur par copie, de l'opérateur d''affection et du destructeur) (il fait la bonne chose ici ), ta classe devrait être comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Task {
        public :
        Task() : buffer(128) { }
        void operator()(int index, int value) {
            buffer[index] = value;
        }
        private :
            std::vector<int> buffer;
    };
    PS : À première vue, j'aime pas du tout l'utilisation de ton operator() (et sa signature).

  5. #5
    Invité
    Invité(e)
    Par défaut
    J'ai changer le code de ma classe mais toujours la même erreur en compilation. :/

    Bref, je ne sais plus trop que faire. :/

    PS : j'ai trouvé la solution, il suffisait d'utiliser un pointeur.

    Code cpp : 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
     
    #include <boost/lockfree/queue.hpp>
    #include <thread>
    class Task {
        public :
        Task();
        void operator()(int index, int value);
        private :
            std::vector<int> buffer;
    };
    Task::Task() : buffer(128) {
     
    }
    void Task::operator()(int index, int value) {
        buffer[index] = value;
    }
    using namespace odfaeg::core;
    using namespace odfaeg::math;
    using namespace odfaeg::physic;
    using namespace odfaeg::graphic;
    using namespace odfaeg::audio;
    int main()
    {
        boost::lockfree::queue<Task*> tasks(128);
        Task t;
        tasks.push(&t);
        FastDelegate<void> fd(&Task::operator(), &t, 0, 255);
        tasks.consume_one(fd);
        return 0;
    }

    Bon maintenant je vais voir avec deux thread ce que ça donne (un qui lis le buffer et un autre qui écrit dans le buffer) pour voir si il n'y a pas de crash.

  6. #6
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Le truc c'est que le destructeur de std::vecteur n'est pas "trivial".
    Pour être thread-safe, utilise plutôt un mutex ?

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/02/2011, 15h10
  2. Réponses: 4
    Dernier message: 24/02/2009, 12h06
  3. Interfaces, Pattern Observer
    Par IProg dans le forum Langage
    Réponses: 8
    Dernier message: 18/12/2003, 14h11
  4. [Design Patterns] Architecture 3 tiers
    Par HPJ dans le forum Design Patterns
    Réponses: 1
    Dernier message: 29/07/2003, 11h49
  5. [langage] expression reguliere motif répétitif dans 1 pattern
    Par comme de bien entendu dans le forum Langage
    Réponses: 11
    Dernier message: 09/04/2003, 16h14

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