【问题标题】:boost thread pool bind errorsboost线程池绑定错误
【发布时间】:2015-06-04 06:08:02
【问题描述】:

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

编译器似乎没有识别出我通过引用传递了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();

这是否意味着我无法从函数中传递或返回值?既然handler所需的签名不带参数也没有返回?

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

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

【问题讨论】:

    标签: c++ multithreading boost


    【解决方案1】:

    boost::bindstd::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.

    【讨论】:

    • 有趣,这就是问题所在。那么boost::ref() 传递了对变量的引用的副本?另外,bind 继续让我头疼:main.cpp:68:10: Variable has incomplete type 'void'
    • @FranciscoAguilera 如果您可以使用auto,那么您使用的是 C++11 或更高版本。我建议在这里使用 lambda 而不是 boost::bind,因为人们似乎发现 lambda 不那么令人困惑。
    • 是的,老实说,我什至不知道 boost::bindstd::bind 是什么,我是 C++ 新手,而且还没有例子。我尝试使用 lambda 并遇到了警告。查看编辑。
    • @FranciscoAguilera 这个blog 可能有助于深入了解bind()
    • @TannerSansbury 尤其是这句话“bind 可用于将用户提供的期望一个参数的函数调整为一个接受零参数的函数对象。”所有其他资源都使绑定的含义和/或它的作用过于复杂,以至于无法理解。 xD
    猜你喜欢
    • 2017-02-24
    • 2011-12-18
    • 1970-01-01
    • 2010-12-15
    • 2012-08-26
    • 2011-05-04
    • 2013-05-28
    • 2014-04-25
    • 2011-09-03
    相关资源
    最近更新 更多