10
votes

Nombre variable de threads asynchronisés avec C ++ 11

Je travaille sur un programme où j'aimerais utiliser ASYNC dans une boucle. Dans le code exemple, j'ai inclus il n'y a que 10 éléments, afin que je puisse facilement créer une variable explicite pour chaque élément. Cependant, dans mon programme principal, le nombre d'éléments du vecteur peut varier. Idéalement, je voudrais créer un vecteur de threads async - un pour chaque élément du tableau - qui sont repoussés sur le vecteur asynchreux comme je me loge. Ils veulent les attendre que tous se terminent, puis utilisez " obtenir () "pour renvoyer toutes leurs sorties.

Le code ci-dessous appellera ASYNC en attribuant une variable explicite pour chaque thread, mais quelqu'un sait-il comment appeler dynamiquement async dans un vecteur sans avoir à affecter explicitement une variable à celle-ci ? Idéalement, j'aimerais que ce programme appelle "STD :: COUT" une fois pour chaque fois qu'il a bouclé, au lieu d'une seule fois. P>

#include <iostream>
#include <vector>
#include <string>
#include <future>

std::string hi (std::string input)
{
    return "hello, this is " + input;
}

int main()
{
    std::vector<std::string> test_vector( 10, "a test" );
    std::future<std::string> a;
    std::future<std::string> b;

    for ( int i = 0; i < test_vector.size ( ); i++ )
    {
        a = std::async(std::launch::async, hi, test_vector[i]);
    }

    std::cout << a.get() << std::endl;

    return 0;
 }


5 commentaires

Et quelle est votre question précisément?


Comment appeler dynamiquement ASYNC Chaque fois que la boucle passe au lieu de devoir créer explicitement une variable.


Le code tel que écrit ci-dessus a une faille grave, chaque fois que vous attribuez un nouvel avenir à A , vous le forcez à bloquer et à attendre que le fil associé à sa valeur ancienne à la fin, vous êtes donc efficacement en marche. en série. Quoi qu'il en soit, je suis surpris que la solution à un nombre dynamique de contrats à terme n'est pas complètement évidente: stockez chaque nouvel avenir dans un conteneur de taille dynamique, comme un vecteur. Vous avez même dit que vous avez même dit que vous-même: "Je voudrais créer un vecteur de threads async - un pour chaque élément de la matrice - qui sont repoussés sur le vecteur async comme je me loge." Alors pourquoi Vous n'avez pas juste fait ça!


Les vecteurs étaient la meilleure façon de le décrire, j'avais essayé d'utiliser ce genre de chose, mais je n'avais aucune vitesse et je voulais voir ce que les autres suggèrent que cela semble être le seul moyen de le faire et que mon programme n'a pas fait 't fonctionne plus vite.


Peut-être que la fonction ASYNC s'appellera de manière récursive? Je ne sais pas si cela est possible et vous devrez attendre les frais généraux d'appeler la première fonction, mais une fois que vous avez deux courants, ces deux en appelleront deux autres et cela augmentera de manière récursive. C'est peut-être ce que vous recherchez. Définissez une variable globale avec un mutex afin que les threads puissent voir le nombre de fils où appelé et interrompt la récursivité.


3 Réponses :


3
votes

Si je comprenais correctement, cela pourrait être quelque chose comme: xxx pré>

désolé je ne peux pas poster comme un commentaire, mais de cette façon, en fonction de la logique, et si cela fonctionne, vous devriez être Capable de manipuler de manière dynamique le vecteur navel code>. p>


update strong> p>

Mieux encore: P>

for(int i=0; i<(int) vessel.size(); i++)
{
    delete vessel[i];
}


4 commentaires

À Cplusplus unique_ptr référence , il est indiqué que actes_ptr objets supprimer automatiquement le Objet Ils gèrent (en utilisant un Delier) dès qu'ils sont eux-mêmes détruits . Merci de le pointer @ 0x499602D2. Ce exemple ilustre comment il devrait être utilisé.


Mieux vaut utiliser des pointeurs bruts (exception-sécurité), encore mieux: n'utilisez pas du tout des pointeurs. Alors que Galiks répond à des spectacles, il est parfaitement raisonnable de ne pas les utiliser. La réduction de l'indirection est une bonne idée (bien que le coût soit probablement négligeable ici).


Même ignorer le fait que votre version "meilleure encore" ne compile pas (vous ne pouvez pas attribuer un std :: futur à un std :: futur * ) il n'y a pas de Raison que ce soit à allouer de manière dynamique les contrats à terme. Vessel.Push_back (STD :: ASYNC (STD :: Launch :: ASYNC, HI) Fonctionne parfaitement, est plus sûr et est au moins aussi efficace car il effectue moins d'allocations et d'indirections du pointeur.


Je vais mettre à jour la réponse. J'aurais dû le tester. Je vais avoir la suspension d'aider les gens ici. C'était juste récemment que j'ai terminé un parcours de POO au collège et j'essaie de le mettre à bon usage.



11
votes

une réponse comprenant std :: cout : xxx


0 commentaires

15
votes

Vous pouvez résoudre ceci en créant un vecteur de futures pour correspondre à votre vecteur de threads, quelque chose comme ceci: xxx

notez l'utilisation de STD :: CREF à réussir par const Référence . Utilisez std :: ref pour réussir Références non const < / em>.