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 :

Design pour arrêter des traitements en environnement multithread


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut Design pour arrêter des traitements en environnement multithread
    Salut,

    Je suis entrain de travailler sur un design pour permettre d'arrêter proprement l'execution de traitement (fonctions de calculs),
    suite au declenchement d'une alerte dans un ou plusieurs threads quelquonque.
    La seule solution que je vois c'est de checker un booléen partout ou je pourrai dans l'execution des fonctions ( technique utilisé aussi pour les annulations )
    quelqu'un a t-il déja employé d'autres techniques plus propres ? ou une version améliorée ?

    J'ai mis le code que je viens d'écrire pour illustrer mon propos...
    j'utilise la bibliothèque boost pour synchronisé les threads.

    ps :
    les threads d'alertes invoqueront la méthode cManager::Alert_all() pour arrêter tout...

    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
    class cFunction;
     
    class cManager
    {
    public :
    	void Alert_All();
    protected :
    	void AddFunction(boost::shared_ptr<cFunction>);
    	void RemoveFunction(boost::shared_ptr<cFunction>);
    private:
    	std::vector<boost::shared_ptr<cFunction> > p_Running;
    };
     
    void cManager::Alert_All()
    {
    	for (size_t i = 0 ; i < p_Running.size(); i++ )
    	{
    		p_Running[i]->set_alert(true);
    	}
    }
     
    class cFunction
    {
    	bool p_alert;
    	boost::mutex p_lock;
     
    public:
    	cFunction();
    	void set_alert(const bool& alert_);
    	bool get_alert();
    	void execution();
    	void alert_clean();
    };
     
     
    void cFunction::execution()
    {
    	// faire des traitements
    	for (unsigned int i = 0; i < 1000; i++)
    	{
    		if (!get_alert())
    		{
    			// traitement boucle
    		}
    	}
     
    	if (!get_alert())
    	{
    		// traitement singulier
    	}
     
    	if (get_alert())
    	{
    		alert_clean();
    	}
    }
     
    cFunction::cFunction() : p_alert(false)
    {
    }
     
    void cFunction::set_alert( const bool& alert_ )
    {
    	boost::mutex::scoped_lock guard(p_lock);
    	p_alert = alert_;
    }
     
    bool cFunction::get_alert()
    {
    	boost::mutex::scoped_lock guard(p_lock);
    	return p_alert;
    }
     
    void cFunction::alert_clean()
    {
    	// opérations pour terminer correctement la fonction
     
    	set_alert(false);
    }

  2. #2
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Bonjour!

    Pourquoi ne pas plutôt utiliser des signaux ou des sémaphores? Ca m'aurait paru plus adaptés non?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    des signaux boost ne sont pas thread safe.
    j'utiliserai boost.asio pour notifier.

    les semaphores, peux tu t'expliquer ?

  4. #4
    Membre éclairé Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Points : 791
    Points
    791
    Par défaut
    Autant pour moi, les sémaphore ne sont pas vraiment indiqué pour ça, je me suis laissé emporté.. (dès que je vois "thread", dans matête ça fait "tilt: sémaphore"... )

    Donc désolé pour mon intervention ^^

  5. #5
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Citation Envoyé par seeme Voir le message
    Autant pour moi, les sémaphore ne sont pas vraiment indiqué pour ça, je me suis laissé emporté.. (dès que je vois "thread", dans matête ça fait "tilt: sémaphore"... )
    Non ce n'est pas si idiot, un sémaphore pourrait être utilisé pour protéger le booléen qui est une ressource commune.

    Mais bon ça reste bourrin comme technique, avec tous les risques d'interblocages qui vont avec, etc...
    Find me on github

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Non ce n'est pas si idiot, un sémaphore pourrait être utilisé pour protéger le booléen qui est une ressource commune.

    Mais bon ça reste bourrin comme technique, avec tous les risques d'interblocages qui vont avec, etc...
    hmm oui j'y pense avec une wait condition sur le booléen.

    Je ne suis pas le seul à coder, dois-je obliger les développeurs à checker partout ou ils peuvent dans le code de leurs fonctions ? c'est étrange comme "archi"
    il y' a pas un système de points d'annulation qui existe pour les threads ?

  7. #7
    screetch
    Invité(e)
    Par défaut
    j'ai eu un peu le même problème mais chez moi le design est (beaucoup) plus complexe.
    Les threads executent des taches dépendantes les unes des autres et il n'est pas possible d'interrompre une tâche en cours. Lorsqu'il n'y a plus de tâches, les threads sont libérés.

    Ici le problème serait que ta méthode "execute" fait trop de choses et son design est très rigide:
    si tu ajoutes de nouvelles phases ou en retire, le code de cette fonction doit être réexaminé et l'utilisation du signal pourrait être cassée.

    Tu pourrais (si ca vaut le coup) généraliser en divisant en sous-tâches qui sont ajoutées dans une liste au tout début. Ensuite a chauqe tour de boucle, on vérifie si le signal est mis. Je vois donc ca comme:
    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
    void cFunction::execution()
    {
        prepare(); //peut être dans le constructeur plutot?
        while (!get_alert() && Task* task = mTaskList.pop())
        {
            task->execute();
        }
        if (get_alert())
        {
            alert_clean();
        }
    }
     
    void cFunction::prepare()
    {
        for (unsigned int i = 0; i < 1000; i++)
        {
            mTaskList.push(new TraitementBoucle(i));
        }
        mTaskList.push(new TraitementSingulier);
    }
    A NOTER que cette facon de faire, bien que plus souple, est beaucoup plus gourmande en ressources (mémoire et CPU, puisqu'il faut allouer toute les tâches et les stocker). A n'utiliser que si tu en as vraiment besoin.
    Il est aussi possible d'optimiser si execute() renvoie la tâche suivante, dans ce cas tu ne stockes pas de liste mais execute() renvoie (et peut-être crée sur demande) la tâche qui devrait être éxecutée ensuite.
    Dans ton cas tu peux avoir une tâche Head qui va automatiquemet te renvoyer une tâche TraitementBoucle, qui se renvoie elle-même 1000 fois puis renvoie une tâche TraitementSingulier, etc etc etc
    enfin tout ca c'est de même, seulement si tu en as besoin.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par ICE Tea Voir le message
    des signaux boost ne sont pas thread safe.
    j'utiliserai boost.asio pour notifier.
    boost::signals2, qui remplace boost::signal dans les "dernières" versions (>= 1.35, me semble-t-il) sont thread safe.

    Cela vaudrait la peine d'être approfondi, non
    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

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,
    boost::signals2, qui remplace boost::signal dans les "dernières" versions (>= 1.35, me semble-t-il) sont thread safe.

    Cela vaudrait la peine d'être approfondi, non
    J' avais étudié la question, disons que boost.signal2 est thread safe lors de l'association du signal et du slot ( connect / disconnect).
    Par contre le concept de "Safe Cross-Thread Signals"
    ( i.e émission d'un signal qui déclenche de façon safe des slots dans des threads différents) n'est pas supporté à ma connaissance

    tu confirmes n'est ce pas ?
    As tu une parade ?

    ps : Le seul qui répond à ce besoin d'après mes recherches c'est QT signal/slot mais je n'aime pas QT car c'est trop intrusif...

  10. #10
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Bonjour,
    Il y as dans les threads de boost un système de point d'interruption:
    http://www.boost.org/doc/libs/1_45_0...anagement.html

    En gros, quand on demande l'arrêt d'un thread, le prochain point d'interuption rencontré par le thread lancera une exception de type boost::thread_interrupted, ce qui arrêtera proprement le thread.

    Par contre il est nécessaire:
    - De rajouter des points d'interruption(ex : boost::this_thread::interruption_point() ) aux endroits stratégiques.
    - D'avoir du code exception-safe

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par screetch Voir le message
    Tu pourrais (si ca vaut le coup) généraliser en divisant en sous-tâches qui sont ajoutées dans une liste au tout début. Ensuite a chauqe tour de boucle, on vérifie si le signal est mis. Je vois donc ca comme:
    Bonne idée,
    Suite à ta remarque j'ai modifié le design, je pense que l'on peut encore généraliser
    le concept d'exécution pas à pas.
    chaque étape peut être modélisée par un couple ( ou plus selon besoin ) de fonctions.
    ( F1 , F2 ) i
    F1 un pointeur de fonction pour éxécuter un traitement à l' étape i
    F2 un pointeur de fonction éxécuter en cas d'échec ( ou abandon ) de l'éxécution F1_i à l' étape i
    ..
    On peut aussi enviseager de donner la possibilité de conserver l'état d'avancement du traitement principal,
    pour permmettre une reprise d'éxecution.

    Dans mon cas j'ai modifié le design en introduisant des pointeurs de fonction généralisés ( boost::function0<bool.. ==> bool f() ) dans une classe cTaskStep,
    J' ai aussi rendu la classe polymorphique pour que les développeurs puissent spécialiser les bonnes méthodes.

    voici le code des déclarations.

    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
     
    class cFunction
    {
    protected :
    	typedef boost::function0<bool> task_type;
    	typedef boost::function0<void> fail_step_type;
     
    	struct cTaskStep 
    	{
    		fail_step_type OnFail;
    		task_type Execute;
     
    		cTaskStep(const fail_step_type& OnFail_,const task_type& Execute_) : OnFail(OnFail_), Execute(Execute_) 
    		{
    		}
     
    		cTaskStep(const task_type& Execute_) : Execute(Execute_) 
    		{
    		}
    	};
     
    private :
    	bool p_alert;
    	boost::mutex p_lock;
    	std::vector<cTaskStep> mTaskList;
     
    public:
    	cFunction();
    	void set_alert(const bool& alert_);
    	bool get_alert();
    	void execution();
    	virtual void alert_clean();
    protected :
    	virtual void prepare();
    	virtual void add_step(const cTaskStep& step_);
    };
    Le code des définitions

    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
     
     
     
    void cFunction::execution()
    {
    	//TO DO protéger par mutex..
    	prepare();
     
    	std::vector<cTaskStep>::const_iterator TaskIterator_= mTaskList.begin();
     
    	while (!get_alert()  && (TaskIterator_) != mTaskList.end() )
    	{
    		if ( (TaskIterator_)->Execute() ) // Execution de l'étape courante ()
    		{
    			TaskIterator_++;
    		}
    		else // En cas d'échec sur cette étape
    		{
    			if ( !((TaskIterator_)->OnFail).empty() ) // permet de vérifier la présence de la callback OnFail()
    			{
    				(TaskIterator_)->OnFail();
    			}
    			break;
    		}
    	}
     
    	if (get_alert())
    	{
    		alert_clean();
    	}
    }
     
    void cFunction::add_step( const cFunction::cTaskStep& step_ )
    {
    	mTaskList.push_back(step_);
    }
    Y' a t-il autre chose que l'on peut faire pour améliorer le design...

  12. #12
    screetch
    Invité(e)
    Par défaut
    je ne suis pas sur, ca me parait pas mal. Les résponsabilités sont beaucoup mieux partagées, et je trouve ca mieux.
    Comme j'avais rajouté par la suite, il est possible de l'améliorer en laissant chaque tâche définir quelle est la tâche suivante. Ca évite des allocations, mais ca "force" chaque tâche a avoir une responsabilité supplémentaire (connaître la tâche suivante).
    La responsabilité de l'ordonnancement peut donc être donné soit a la méthode "prepare" comme tu as faait (ma version préférée mais qui consomme un peu de mémoire) soit divisée et distrbuée a chaque tâche (on evite quelques allocations mais le design force chaque tâche a avoir connaissance de la tâche suivante).

    Mais comme c'est là, moi je trouve ca vraiment pas mal

  13. #13
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Deux choses sur ces tâches courtes :

    1) si l'ordre des tâches est important, je suis en train de réfléchir à la notion de pipeline généralisé (réversible et non réversible). Ca pourrait coller avec l'idée de continuer un traitement tant qu'il n'échoue pas. Que ceux qui m'aiment me suivent (par MP, dans un premier temps).

    2) si l'ordre des tâches n'est pas important je continue de proposer la vision de tasklet définie par Lionel Lemarié pour ses optimisations multicore sur PS3. L'idée est de faire de pool de tâches très courtes et indépendantes les unes des autres, et de laisser les threads (mappées à des threads hardware pour plus de performance sur les plateformes supportant cette possibilité) récupérer la prochaine tâche, l'exécuter, etc. Le tout, sans synchronisation explicite grâce à une liste lock free.

    Je ne sais pas si ça peut aider ; c'était juste mon intervention peu utile du jour
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  14. #14
    screetch
    Invité(e)
    Par défaut
    le 2) c'est ce que j'ai entrepris sur mon code personnel, les taches peuvent être divisibles et découpées en tasklets. un certain nombre de threads attendent une tâche, la coupent en morceaux eventuellement et executent tous les bouts.
    A un plus haut niveau, les tâches dépendent les unes des autres ce qui permet d'avoir un certain ordonnancement.
    D'ailleurs c'est le seul système qui s'éxecute, il n'y a plus de "thread principal" ou de bloucle principale. La tâche 1 lance la tache 2 qui lance la 3... qui reboucle sur la 1 et c'est reparti pour un tour.

    C'est valable seulement si il y a beaucoup de tâches, ou si les tâches sont longues, sinon ca ne fait que ralentir.

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Nogane Voir le message
    Bonjour,
    Il y as dans les threads de boost un système de point d'interruption:
    http://www.boost.org/doc/libs/1_45_0...anagement.html

    En gros, quand on demande l'arrêt d'un thread, le prochain point d'interuption rencontré par le thread lancera une exception de type boost::thread_interrupted, ce qui arrêtera proprement le thread.

    Par contre il est nécessaire:
    - De rajouter des points d'interruption(ex : boost::this_thread::interruption_point() ) aux endroits stratégiques.
    - D'avoir du code exception-safe
    Interressant je vais tester cette technique.

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Dans mon cas l'ordre a une importance, ce sont des algos.
    Par contre je ne connais pas ce concept de pipeline généralisé.

  17. #17
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Un pipeline y = P(x), c'est une suite de fonctions F0(), .... Fn() qui sont utilisées en séquence, de sorte que :

    y = P(x) = Fn(Fn-1(....F0(x)...));

    ou, dans un langage plus mathématique : P(x) = (Fn ∘ Fn-1 ∘ .... ∘ F1 ∘ F0)(x)

    Le généraliser (dans une vision C++), ça serait donner la possibilité à l'utilisateur de

    1) sélectionner les fonctions qui doivent être exécutées
    2) sélectionner la façon dont les paramètres sont passés (paramètre de la fonction == résultat de la fonction précédente ? ou autre chose ?)
    3) sélectionner la façon dont le pipeline s'arrête (arrêt unique à la fin ? arrêt entre chaque évaluation de fonction ?)

    etc. Au final, ce pipeline généralisé serait donc une liste de tâche dont une particularité serait qu'elle peut fonctionner sous la forme d'un véritable pipeline. En C++, ça va être super tordu
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  18. #18
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Pour compléter ta liste
    - Il faut pouvoir introduire des étapes imbriquées ( sous-tâches )
    - Comment gérer les étapes conditionnelles() (i.e if-elseif else )
    - Pouvoir accéder aux étapes directement ( sans trop d'indirections...)

    A défaut de faire l'implémentation il faut qu'on arrive à figer une Interface...

    Ou en es tu ?

    On n'arrive pas à t'envoyer de MP...

  19. #19
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par ICE Tea Voir le message
    Pour compléter ta liste
    - Il faut pouvoir introduire des étapes imbriquées ( sous-tâches )
    - Comment gérer les étapes conditionnelles() (i.e if-elseif else )
    - Pouvoir accéder aux étapes directement ( sans trop d'indirections...)
    Ca me semble exagéré. Le conditionnel peut être traité avec un pipeline dans une fonction qui effectue un test. Quand à l'ajout d'une fonction intermédiaire, ça n'a de sens que si son entrée et sa sortie ont le même type (ce qui peut arriver, bien évidemment). Par contre, j'ai du mal à voir un cas d'utilisation probant.

    Citation Envoyé par ICE Tea Voir le message
    A défaut de faire l'implémentation il faut qu'on arrive à figer une Interface...
    Comme il risque fort d'y avoir beaucoup de magie à l'intérieur (je le pressens), ça pourrait être un plus effectivement d'essayer de spécifier ça.

    Je vais voir ça ce soir.

    Citation Envoyé par ICE Tea Voir le message
    Ou en es tu ?

    On n'arrive pas à t'envoyer de MP...
    Boite pleine. Mais je l'ai vidé.

    Quand à où j'en suis, et bien, j'ai beaucoup de choses à faire ; il faut que je corrige ce satané SHA256, que j'implémente une lib TCP/IP, que je revoie mon système de dispatch de messages ; à ce moment, je commencerais à avoir besoin d'un pipeline (puisque je vais recevoir des messages cryptés, encodés en base64 (ou pas, d'ailleurs), que je vais devoir décoder, décrypter, puis interpréter. L'interface que j'ai à l'heure actuel prévu n'est pas idéale, même si elle est pratique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    blowfish_cryptograph c;
    blowfish_key k;
    std::string b64_from_socket = ...;
    std::vector<unsigned char> out;
    c.decrypt(k, b64_from_socket, out, decoder::base64());
    ...
    Peut mieux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pipeline<???> p = make_pipeline(decoder::base64_pipe(), symetric_cryptograph_pipe<bf_engine>(k));
     
    pipeline << b64_from_socket >> out; // ou quelque chose comme ça ; ça, c'est pas beau.
    Dans l'idée, je ne devrais pas à me soucier de ce qu'il y a dans le pipeline ; ça devrait fonctionner tout seul.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  20. #20
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @Emmanuel Deloget: Je t'avais répondu, je te réenvoie le MP.

    Pour la fin de ton message, j'aurais plus vue ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    out = pipeline(in);
    Comme un foncteur, j'avais pas pensé au opérateur de flux, mais je verrais plus ca écrit avec les deux même opérateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    out << pipeline << in;
    //ou
    in >> pipeline >> out;
    En le fait d'avoir deux sens pourrait être pratique pour un pipeline réversible, AMA.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Les design pattern pour créer des jeux
    Par alex6891 dans le forum Design Patterns
    Réponses: 4
    Dernier message: 26/11/2018, 19h59
  2. Réponses: 4
    Dernier message: 14/06/2010, 21h18
  3. [W98] Un équivalent au gestionnaire des tâches (pour arrêter des processus)
    Par annedeblois dans le forum Windows 2000/Me/98/95
    Réponses: 2
    Dernier message: 28/09/2007, 17h36
  4. Aide pour définir des index (traitement long)
    Par m-mas dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 25/05/2006, 20h39
  5. Réponses: 11
    Dernier message: 03/11/2005, 17h59

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