boost::io_service post using a lambda

boost::io_service post using a lambda

本文关键字:using lambda post service io boost      更新时间:2023-10-16

此问题与上一个问题有关。

我已经实现了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行。这让我觉得标头没有被正确解析。我在没有模板的情况下尝试,只是将引用传递给我的工人类,并且没有转发。

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:的成员

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

PS:上面的代码http://ideone.com/g38Z4H是我的g++骨架(有效)。这个http://ideone.com/d7Nkop另存为host.cu也展示了这个问题。

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

这个构造:

[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();
                     });
}

我发现了问题。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)
{}

似乎已经修复了错误,代码现在正在编译。非常感谢所有提供帮助的人。