2016-11-11 61 views
0

我想在C++中创建一个线程池。概念是main将创建一个新的Task,并且ThreadPool类将获得Task对象并实现其他工作。这是任务等级:绑定返回值和可变参数模板

template<typename ... Arguments> 
     class Task{ 
      // 
     public: 
      Task(std::function<void (Arguments...)> _func, Arguments... _args){ 
       auto f1 = std::bind(_func, _args...); 
       f1(); 
      }; 
      void run(){ 

      }; 
     }; 

,这我是多么想使用它:

#include <iostream> 
#include <algorithm> 

#include "Task.hpp" 

void prtinhi(int a) 
{ 
    std::cout << a << std::endl; 
    return; 
} 

int main(){ 

    Task<int> task(prtinhi, 5); 
    task.run(); 
    return 0; 
} 

显然,工作对象将在线程池被传递和线程池将调用的run()根据一些逻辑。 此代码运行成功打印5.但我想要的是从run()函数调用f1()。如果我改变Task类有auto f1确定指标作为类成员,我得到一个错误:

non-static data member declared ‘auto’ 

我若静,我不能一个值分配给它。 那么我该如何解决这个问题呢?有没有更好的方法来做到这一点?

+0

'decltype'也许? – DavidW

+0

我不明白如何decltype可以帮助我在这里... –

回答

2

为什么任务需要知道函数参数?该任务应该是一个void()类型擦除的可调用对象。

using Task = std::function<void()>; 
Task task([]{ prtinhi(5); }); 

ThreadPool pool; 
pool.schedule(task); 
// ... 
// `prtinhi(5)` will be eventually called. 

如果您需要获取返回值,您需要std::future

ThreadPool可以实现如下:

struct ThreadPool 
{ 
    some_lockfree_queue<Task> _queue; 
    std::vector<std::thread> _workers; 

    void initialize() 
    { 
     for(int i = 0; i < num_threads; ++i) 
     { 
      _workers.emplace_back([this] 
      { 
       Task t = _queue.try_dequeue(); 
       t(); 
      }); 
     } 
    } 
}; 

std::bind(看this talk by STL获取更多信息)。您应该使用lambdas来绑定您需要的参数并返回无效函数。

+0

链接到确切的时间在谈话重新:绑定问题:https://youtu.be/zt7ThwVfap0?t = 1721 – Shillard