2014-11-17 15 views
7

Döngüde uyumsuzluğu kullanmak istediğim bir program üzerinde çalışıyorum. İçerdiğim örnek kodda sadece 10 öğe var, bu yüzden her öğe için kolayca bir değişken oluşturabilirim. Ancak, ana programımda, vektördeki elemanların sayısı değişebilir. İdeal olarak, asenkron iş parçacıklarının bir vektörünü oluşturmak istiyorum - dizideki her eleman için bir tane - ki ben döngüsel vektörde geri dönerken tekrar dönüyorum. Sonra hepsini tamamlamak için beklemek istiyorum ve sonra kullanıyorum " tüm çıkışlarını geri almak için()C++ 11 ile değişken sayıda asenkron iş parçacığı sayısı

aşağıda kodu, her iş parçacığı için açık bir değişken atayarak asenk arayacak ama kimse dinamik açıkça bunun için bir değişken atamak zorunda kalmadan bir vektör içinde uyumsuz çağrı nasıl biliyor? İdeal olarak, bu programın her seferinde bir kez değil, bir kez yerine "std :: cout" adını vermesini istiyorum.

#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; 
} 
+0

Ve sorunun ne olduğunu tam olarak nedir? – Columbo

+0

Açıkça bir değişken oluşturmak zorunda kalmadan döngü geçirildiğinde her zaman uyumsuz olarak nasıl çağrılır? –

+0

Yukarıda yazılı olan kodun ciddi bir kusuru vardır, her bir yeni atamayı atadığınız zaman, 'a' bunu engellemek ve eski değeriyle ilişkilendirilen iş parçacığının bitmesini beklersiniz, bu nedenle seri olarak etkili bir şekilde çalışıyorsunuzdur. Her neyse, dinamik bir dizi geleceğin çözümünün tamamen açık olmadığını şaşırıyorum: Her yeni geleceği bir vektör gibi dinamik büyüklükte bir konteynırda saklayın. Kendiniz de söylediniz: _ "Asenkron iş parçacıklarının bir vektörünü oluşturmak istiyorum - dizideki her eleman için bir tane - ki bunlar async vektörüne geri döndüğümde geri itiliyor." yap bunu! –

cevap

7

std::cout dahil bir cevap:

std::vector<std::future<std::string>> a; 
for (int i = 0; i < 10; ++i) { 
    a.emplace_back(std::async(hi)); 
} 
for (auto& element : a) { 
    std::cout << element.get() << std::endl; 
} 
3

Eğer doğru anladıysam, olabilir gibi bir şey:

Ben mantığı bağlı bir yorumun, ancak bu şekilde, olarak açamazsınız, ve eğer çalışırsa, o zaman olmalı
std::vector<std::future<std::string>> vessel; 
for (int i = 0; i < test_vector.size (); i++) 
{ 
    std::future<std::string> aux; 
    aux = std::async(std::launch::async, hi); 
    vessel.push_back(aux); 
} 

Maalesef vessel vektörünü dinamik olarak manipüle edebilir.


daha iyisi Güncelleme

: Açıkça bir değişken bildirmek gerekmez

vessel.push_back(new std::future<std::string>); 
vessel[vessel.size()-1] = std::async(std::launch::async, hi); 

bu şekilde. Ama bir kez yapılır delete gerekir:

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

Belleği yönetmek için 'std :: unique_ptr' kullanmalısınız. – 0x499602D2

+0

[CPlusPlus unique_ptr referansı] 'nda (http://www.cplusplus.com/reference/memory/unique_ptr/), 'unique_ptr nesnelerinin, kendileri en kısa sürede yönetdikleri nesneyi (bir delici kullanarak) otomatik olarak sildiği belirtilir. destroyed'. @ 0x499602D2'yi işaretlediğiniz için teşekkürler. Bu [örnek] (http://www.cplusplus.com/reference/memory/unique_ptr/get/) nasıl kullanıldığını gösterir. – GChamon

+3

Daha iyi ham işaretçiler (istisna güvenliği) kullanmayın, daha iyisi: işaretçileri hiç kullanmayın. Galiks'in gösterdiği gibi, bunları kullanmamak kesinlikle mantıklı. Dolaylılığın azaltılması iyi bir fikirdir (maliyetin muhtemelen ihmal edilebilir olmasına rağmen). – stefan

12

Sen ipler vektör maç için vadeli bir vektör oluşturarak bu çözebilir, böyle bir şey: std::cref kullanımı Kat geçmek zorundadır

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

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

int main() 
{ 
    std::vector<std::string> tests = {"one", "two", "three", "four"}; 
    std::vector<std::future<std::string>> futures; 

    // add the futures to the futures vector as you launch 
    // your asynchronous functions 
    for(auto&& t: tests) 
     futures.emplace_back(std::async(std::launch::async, hi, std::cref(t))); 

    // collect your results 
    for(auto&& f: futures) 
     std::cout << f.get() << '\n'; 
} 

Not referans. olmayan const başvuruları geçmek için std::ref kullanın.

+2

+1 –

+0

'(auto && f: futures)' için bu, – GChamon

+2

öğrenmek zorunda olduğum bir şeydir ['std :: future :: valid'] (http://en.cppreference.com/w/cpp/thread/future/ geçerli) burada, her zaman doğru döner. – Casey