提升线程池绑定错误

时间:2015-03-31 02:23:10

标签: c++ multithreading boost

我使用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();

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

现在可以使用,但我真的想知道为什么我不能传递参数或返回值,只能传输捕获的变量或来自范围之外的变量:/

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

1 个答案:

答案 0 :(得分:1)

boost::bind,与std::bind一样,按值获取模板参数。

参数最终将被绑定到参考的函数并不重要。该副本已经尝试过。

您可以通过使用boost::ref包装参数来解决此问题。或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.