提升线程池绑定错误

boost thread pool bind errors

我正在使用 boost::asioboost::filesystem 来执行一些简单的异步文件系统操作。 下面的代码片段应该为它在第一级中找到的每个目录生成一个新线程,该目录递归此类目录,依此类推,只要线程池中有线程可供使用。

编译器似乎无法识别我通过引用传递 boost::asio::io_service,并抱怨:

main.cpp:51:51: Call to implicitly-deleted copy constructor of 'boost::asio::io_service'

我试过 #define BOOST_ASIO_HAS_MOVE 所以它会认为允许移动 boost::asio::io_service 即使它确实被 const & 传递,但无济于事。

包括:

#include <iostream>
#include <thread>
// Threadpool
#define BOOST_ASIO_HAS_MOVE
#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
// Filesystem
#include <boost/filesystem.hpp>

主要:

int main(int argc, const char * argv[]) {
    boost::asio::io_service ioservice;
    boost::thread_group threadpool;
    boost::asio::io_service::work work(ioservice);
    unsigned int threads = std::thread::hardware_concurrency();
    for(unsigned int i = 0; i < threads; ++i)
        threadpool.create_thread(boost::bind(&boost::asio::io_service::run,
                                 &ioservice));


    ioservice.post(boost::bind(parallel_found_file,
                               ioservice, // Call to implicitly-deleted copy constructor of 'boost::asio::io_service'
                               APPS_DIR,
                               FILE_NAME));
    threadpool.join_all();
    ioservice.stop();

    return 0;
}

函数:

static bool parallel_found_file(boost::asio::io_service & ioservice,
                                 const boost::filesystem::path & dir_path,
                                 const std::string & file_name)
{
    if(!exists(dir_path))
        return true;

    boost::filesystem::directory_iterator end_itr;
    for(boost::filesystem::directory_iterator itr(dir_path);
        itr != end_itr;
        ++itr )
    {
        if(is_directory(itr->status()))
        {
            ioservice.post(boost::bind(parallel_found_file,
                                       ioservice, // Call to implicitly-deleted copy constructor of 'boost::asio::io_service'
                                       itr->path(),
                                       file_name));
        }
        else
        {
            if(itr->path().filename().string().find(file_name)
               != std::string::npos)
            {
                return true;
            }
        }
    }
    return false;
}

编辑:

ioservice.post(boost::bind(parallel_remove_file,
                           boost::ref(ioservice),
                           boost::ref(APPS_DIR),
                           boost::ref(FILE_NAME)));

io_service.hpp:102:3: Static_assert failed "CompletionHandler type requirements not met"

boost::asio::io_service::post says: 处理程序的函数签名必须是: void handler();

这是否意味着我无法从函数中传递或 return 值?由于处理程序所需的签名不带参数并且没有 return?

这现在有效,但我真的很想知道为什么我不能传递参数或 return 值,只能传递捕获的变量或范围外的变量:/

auto ioref = std::ref(ioservice);
ioservice.post([ioref]()
               -> void
               { parallel_remove_file(ioref, APPS_DIR, FILE_NAME); });

boost::bind,像std::bind通过值获取其模板参数。

参数最终将绑定到采用引用的函数并不重要。已尝试复制。

您可以通过用 boost::ref. Or std::ref 包裹参数来解决这个问题。任何一个都将创建一个对象,该对象的行为类似于对原始包装对象的引用,即使在复制时也是如此。

result = ioservice.post(boost::bind(parallel_found_file,
                                    boost::ref(ioservice),
                                    itr->path(),
                                    file_name));

您有责任确保 ioservice 与绑定函数一样长。

此外,无法将参数传递给 io_service::post,您必须通过 lambda 捕获列表或绑定捕获变量。 See this link.