Traitement de données LIDAR acquises en sous bois, extraction par méthodes tomographiques de données individuelles d'arbre, localisation, diamètre, volumétrie.

Note de traduction : file (de calcul) en français traduit Thread, futures et promises peuvent être traduits par futur et promesses

Futures et promises sont des outils permettant de passer des données d'une file de calcul à une autre. Bien que ceci puisse être fait par d'autres moyens, telles que les variables globales Futures et promises peuvent travailler sans elles. En outre vous n'avez pas à gérer vous même la synchronisation.

Un future est une variable qui reçoit une valeur depuis une autre file de calcul. Si vous accéder à un Future pour obtenir sa valeur vous devez attendre que l'autre file ait fourni la valeur par le promise.   Boost.Thread fournit la méthode boost::future pour créer un future. La classe définit une méthode  get() pour accéder à la valeur get() est une fonction bloquante qui peut avoir à attendre la fourniture de la valeur depuis une autre file de calcul par le promise.

Pour assigner une valeur dans un future un promise est nécessaire,  car boost::future ne fournit pas de méthode pour initialiser une valeur.

Boost.Thread fournit la classe boost::promise, dont une fonction membre set_value(). Vous pouvez toujours utiliser future et promise comme une paire liée. Vous pouvez obtenir un future depuis un promise avec get_future(). Vous pouvez utiliser le future et le promise dans différentes files. Si une valeur est assignée dans le promise d'un thread il peut être récupéré depuis le future d'un autre thread.

#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include 
#include 
/**
 * Assignation de la valeur
 */
void accumulate(boost::promise &p)
{
  int sum = 0;
  for (int i = 0; i < 5; ++i)
    sum += i;
  p.set_value(sum);
}

int main()
{
  boost::promise p;
  boost::future f = p.get future();
  boost::thread t{accumulate, std::ref(p)};
  std::cout << f.get() << '\n';
}

L’exemple précédent utilise un future et un  promise. le future f est récupéré depuis le  promise p qui le construit, ce qui le lie. Une référence au promise est alors passé au thread t qui exécute la fonction  accumulate() . La fonction accumulate() calcule le total de la somme des nombres entre 0 et 5 et stocke le résultat dans le promise. Dans main() f.get() est appelé pour écrire le résultat vers la sortie standard.

Le future f et le promise p sont liés, car p crée f. Quand la méthode get() du future f est appelée, la valeur stockée dans le promise est renvoyée. Car l’exemple utilise deux files(thread), celui principal et intrinsèque au main() et celui t crée au sein du main(). Aussi il est possible que f.get() soit activé avant que la fonction accumulate du second thread t ait stocké le résultat dans le promise pour le future. Dans ce cas f.get bloque le thread initial jusqu’à ce qu’une valeur soit affectée par la fonction accumulateur dans le promise depuis le second thread par p.set_value(sum).

La fonction accumulate() doit être adaptée pour être exécutée dans un thread. Elle doit prendre un paramètre de type boost::promise et stocker le résultatdans ce paramètre.

L’exemple suivant présente boost::packaged_task, une classe qui fait suivre une valeur issue de n’importe quelle fonction vers un future si la fonction renvoie le résultat par un return.

#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include 
#include 

int accumulate()
{
  int sum = 0;
  for (int i = 0; i < 5; ++i)
    sum += i;
  return sum;
}

int main()
{
  boost::packaged_task task{accumulate};
  boost::future f = task.get_future();
  boost::thread t{std::move(task)};
  std::cout << f.get() << '\n';
}

 Ceci est moindrement lisible, car la fonction qui est mise dans le thread est accumulate().

L’exemple qui précède est similaire au précédent, mais dans ce cas boost::promise n’est pas utilisée.Ici la classe boost::packaged_task, qui, comme boost::promise, fournit une fonction membre get_future() qui renvoie un future.

Le constructeur de boost::packaged_task attend comme paramètre la fonction qui sera exécutée dans le thread, mais boost::packaged_task ne lance pas un thread elle-même. Un objet de type boost::packaged_task doit être passé auconstructeur de boost::thread pour que la fonction soit exécutée dans un nouveau thread.

L’avantage de boost::packaged_task est qu’il stocke la valeur en retour de fonction dans un future. Vous n’avez pas besoin d’adapter cette fonction pour stocker cette valeur dans un future. boost::packaged_task peut être vue comme un adaptateur, une interface qui est capable de stocker la valeur retournée dans un future.

Bien que l’exemple se débarasse de boost::promise, l’exemple suivant n’utilise pas boost::packaged_task ni boost::thread

#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include 

int accumulate()
{
  int sum = 0;
  for (int i = 0; i < 5; ++i)
    sum += i;
  return sum;
}

int main()
{
  boost::future f = boost::async(accumulate);
  std::cout << f.get() << '\n';
}

 Dans l’exemple précédent, accumulate() est passé à la fonction boost::async(). Cette fonction unifie boost::packaged_task et boost::thread. Elle démarre accumulate() dans un nouveau thread et retourne un future.

C’est possible de passer une règle de démarrage à boost::async(). Ce paramètre additionnel détermine si boost::async() executer la fonction dans un nouveau thread ou dans le thread courant. Si vous passez boost::launch::async, boost::async() démarrera un nouveau thread; c’est le comportement par défaut. Si vous passez boost::launch::deferred, la fonction sera exécuter dans le nouveau thread quand get() est appelé.

Quoique Boost 1.56.0 permette soit boost::launch::async soit boost::launch::deferred d’être passé à boost::async(), l’exécution dans le thread courant n’est pas encore implémenté, donc si vous passez boost::launch::deferred, le programme se terminera.

 

 

Nous utilisons des cookies. Ils sont activés sur ce sites/, êtes vous d'accord ? Des infos sur les Cookies => ICI informations privées.

  J'accepte les cookies de ce site.
EU Cookie Directive plugin by www.channeldigital.co.uk