2017-06-21 5 views
1

La question que j'ai est la ligne où j'indique ERROR ci-dessous donne une erreur car le constructeur std :: thread calcule la fonction à invoquer et nécessite le paramètre requis par la signature de la fonction.possibilité d'exécuter une tâche empaquetée avec les paramètres de la fonction std :: bind dans un thread séparé via la fonction template

Y at-il un moyen de résoudre ce problème? Si je tente de décoder le nom de la fonction et la liste des arguments de packaged_task, je ne peux pas utiliser la fonction get_future sur une tâche empaquetée et j'ai besoin d'ajouter mon propre code promesse/future pour gérer cela.

#include<iostream> 
#include<string> 
#include<thread> 
#include<future> 
#include<functional> 

using namespace std; 

int sampleAddFunction(const int& a, const int& b) 
{ 
    int sum = a + b; 
    cout << "sum = " << sum << endl; 
    return(sum); 
} 

template<typename T> T asyncExecutor(std::packaged_task<T(T, T)>&& package) 
{ 
    std::future<T> result = package.get_future(); 
    std::thread task_td(std::move(package)); // ERROR here as the std::thread identifies the function name from package and requires the params to be passed. How to handle this ? 
    task_td.join(); 
    return(result.get()); 
} 

int main(int argc, char* argv[]) 
{ 

    // Executing via directly calling through main. 
    int testResult1 = sampleAddFunction(100, 200); 
    cout << "testResult1 = " << testResult1 << endl; 

    // Attempt to create a std::packaged_task and then run it in another thread. 
    std::packaged_task<int(int,int)> task(std::bind(sampleAddFunction, 10, 20)); 
    std::future<int> result = task.get_future(); 
    std::thread t(std::move(task), 100, 200); // 100 and 200 are dummy parameters. 
    t.join(); 
    int testResult2=result.get(); 
    cout << "testResult2 = " << testResult2 << endl; 

    // Attempt to run this in seperate thread and get results. 
    std::packaged_task<int(int,int)> task2(std::bind(sampleAddFunction, 15, 27)); 
    int testResult3 = asyncExecutor<int>(std::move(task2), 100, 200); 
    cout << "testResult3 = " << testResult3 << endl; 

} 

Répondre

0

Cela devrait fonctionner.

#include<iostream> 
#include<string> 
#include<thread> 
#include<future> 
#include<functional> 

using namespace std; 

int sampleAddFunction(int a, int b) 
{ 
    int sum = a + b; 
    cout << "sum = " << sum << endl; 
    return(sum); 
} 

template<typename R, typename F, typename... Ts> 
R asyncExecutor(F&& package, Ts... args) 
{ 
    std::future<R> result = package.get_future(); 
    std::thread task_td(std::move(package), args...); 
    task_td.join(); 
    return(result.get()); 
} 

int main(int argc, char* argv[]) 
{ 
    std::packaged_task<int(int,int)> task2(sampleAddFunction); 
    int testResult3 = asyncExecutor<int>(std::move(task2), 15, 27); 
    cout << "testResult3 = " << testResult3 << endl; 
} 
0

Vous construisez un packaged_task binaire (std::packaged_task<int(int,int)>) d'une fonction arité, le résultat de votre bind (std::function<int()>).

Vous devez soit pas utiliser bind, ou ont asyncExecutor accepter un packaged_task arité (std::packaged_task<T()>)

int sampleAddFunction(const int& a, const int& b) 
{ 
    int sum = a + b; 
    cout << "sum = " << sum << endl; 
    return(sum); 
} 

template<typename T, typename ... ARGS> T asyncExecutor(std::packaged_task<T(ARGS...)>&& package, ARGS ... args) 
{ 
    std::future<T> result = package.get_future(); 
    std::thread task_td(std::move(package), args...); 
    task_td.join(); 
    return(result.get()); 
} 

int main(int argc, char* argv[]) 
{ 
    std::packaged_task<int()> task(std::bind(sampleAddFunction, 10, 20)); 
    int testResult = asyncExecutor(std::move(task)); 
    cout << "testResult = " << testResult << endl; 
    std::packaged_task<int(int,int)> task2(sampleAddFunction); 
    int testResult2 = asyncExecutor(std::move(task2), 15, 27); 
    cout << "testResult2 = " << testResult2 << endl; 
}