使用lambda来提升:: io_service帖子

时间:2015-11-24 20:36:09

标签: c++ c++11 boost lambda cuda

此问题与this previous question有关。

我实施了Richard Hodges在那里发布的代码。 当我使用g++ (Debian 4.8.4-1) 4.8.4时,发布的代码对我有用。

但是,该实现是CUDA库的一部分,我坚持使用CUDA 6.5,它非正式地支持C ++ 11特性。

当我使用Richard发布的代码时:

template <class F>
void submit( F&& f)
{
    std::unique_lock<std::mutex> lock(_cvm);
    ++ _tasks;
    lock.unlock();
    _io_service.post(
    [this, f = std::forward<F>(f)]
                     {
                         f();
                         reduce();
                     });
}

我收到错误:error: expected a "]"指的是lambda行。 这让我觉得标头没有被正确解析。 我尝试了没有模板,只是将引用传递给我的worker类,而没有转发。

void submit( trainer & job)
{
    std::unique_lock<std::mutex> lock(_cvm);
    ++ _tasks;
    lock.unlock();
    _io_service.post([this,&]
                     {
                         job();
                         reduce();
                     });
}

我得到error: an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list

所以我明确添加了thisjob

void submit( trainer & job)
{
    std::unique_lock<std::mutex> lock(_cvm);
    ++ _tasks;
    lock.unlock();
    _io_service.post([this,&job]
                     {
                         job();
                         reduce();
                     });
}

此时,我遇到了错误:

error: could not convert ‘{{((cuANN::trainer_pool*)this)->cuANN::trainer_pool::_io_service}}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::io_service::work’ boost::asio::io_service::work _work { _io_service };

仅供参考,cuANN::trainer_pool是Richard的示例中的worker_pool,而线程池实现,而_io_service只是class trainer_pool的成员:< / p>

class trainer_pool
{   
public:
    trainer_pool ( unsigned int max_threads );
    void start();
    void wait();
    void stop(); 
    void thread_proc();
    void reduce();
    void submit( trainer & job);

private:
    unsigned int _max_threads_;
    boost::asio::io_service _io_service;
    boost::asio::io_service::work _work { _io_service };
    std::vector<std::thread> _threads;
    std::condition_variable _cv;
    std::mutex _cvm;
    size_t _tasks = 0;
};
  1. 我做错了什么?
  2. 如何使用std :: bind或boost :: bind代替使用lambda?
  3. PS:http://ideone.com/g38Z4H上的代码是我的g ++骨架(有效)。 保存为host.cu的{​​{3}}也会显示问题。

    nvcc -std=c++11 host.cu -lboost_thread -lboost_system -lpthread -o host

2 个答案:

答案 0 :(得分:2)

这个结构:

[this, f = std::forward<F>(f)]

是c ++ 14,不会在c ++ 11中编译。

使用[this, &]将是一个错误,因为无法保证函数对象仍然存在(您通过引用捕获它)

在c ++ 11中考虑[this, f]来复制。

编辑:刚才意识到工作是可变的,因此:

void submit(trainer & job)
{
    std::unique_lock<std::mutex> lock(_cvm);
    ++ _tasks;
    lock.unlock();
    _io_service.post([this,job]()->void mutable
                     {
                         job();
                         reduce();
                     });
}

答案 1 :(得分:1)

我发现了问题。 NVCC和CUDA与lambdas一起工作正常。

违规行在标题中:

boost::asio::io_service::work _work { _io_service };

CUDA 6.5不喜欢初始化列表。 将它移动到构造函数:

trainer_pool (unsigned int max_threads)
:_max_threads_(max_threads), _work(_io_service)
{}

似乎修复了错误并且代码现在编译。 非常感谢所有帮助过的人。