boost:bind 和 io_service 在两个不同的 类

boost:bind and io_service in two different classes

我是 Boost 的新手。

我想知道如何在一个 class 中构造一个 io_service 并从另一个 class 向它发送任务。

我的问题是 BOOST_ASIO_COMPLETION_HANDLER_CHECK 抱怨不让代码编译。

他是我代码的骨架:

type_defs.h(这个有打包发送到io_service的功能)

#include "boost/filesystem.hpp"

namespace fs = ::boost::filesystem;

typedef boost::function<void(const fs::path path)> parse_and_aggregate_fun_t;

io_service_processors.h(这是将构建 io_service 并等待作业 post 的 class)。

namespace asio = boost::asio;

typedef std::unique_ptr<asio::io_service::work> work_ptr;

class io_service_processors {
public:
    io_service_processors(int tc);
    virtual ~io_service_processors();

    void init();
    void post_job(parse_and_aggregate_fun_t file_job);

private:
    int thread_count;
    asio::io_service* service;
    boost::mutex mtx;
    work_ptr * work;
    boost::thread_group workers;
};

io_service_processors.cpp

namespace asio = boost::asio;   

io_service_processors::io_service_processors(int tc):thread_count(tc) {

}

io_service_processors::~io_service_processors() {
       // clean up code here removed.
}

void io_service_processors::init() {
    this->service = new asio::io_service();
    this->work = new work_ptr(new asio::io_service::work(*(this->service)));
    for(int i = 0; i < this->thread_count; ++i)
        this->workers.create_thread(boost::bind(&asio::io_service::run, this->service));
}

void io_service_processors::post_job(parse_and_aggregate_fun_t file_job) {
    this->service->post(file_job);
}

job_discoverer.cpp(这将发现文件并将它们的路径发送到 io_service,函数 parse_and_aggregate 将实际打开文件并处理它,process 将简单地 post 到 io_service 的包装函数,this->processor 只是指向上面 class 的 io_service 包装器的指针)。

void job_discoverer::process(const fs::path path){
    std::cout << "Posting file: " << path.string() << std::endl;
    if(this->processor)
        this->processor->post_job(
                boost::bind(&job_discoverer::parse_and_aggregate, this, path)
                );
}

void job_discoverer::parse_and_aggregate(const fs::path path) {
    std::cout << "Parsing and aggregating file: " << path.string() << std::endl;
}

io_service_processors::post_job 中,您将 parse_and_aggregate_fun_t 放入 io_service::postio_service::post must be void()handler 的函数签名。你的是 void(const fs::path)

this->service->post(file_job);

尝试 post 一份工作,但它不是空函数。这当然不行。您是要将值绑定到 path 参数吗?

更有趣的是,该函数 (io_service_processors::post_job) 从未被使用过。如果我们 - 出于幽默的缘故 - 假设 post_job 实际上是指 post_file_job 被写入的地方,那么你会发现你实际上传递了一个 nullary 绑定表达式。所以,修复它:

typedef boost::function<void()> any_job;

Live On Coliru

#include <boost/filesystem.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>

namespace fs = ::boost::filesystem;

typedef boost::function<void()> any_job;

#include <boost/asio.hpp>
namespace asio = boost::asio;

typedef std::unique_ptr<asio::io_service::work> work_ptr;

class io_service_processors {
public:
    io_service_processors(int tc);
    virtual ~io_service_processors();

    void init();
    void post_job(any_job file_job);

private:
    int thread_count;
    asio::io_service* service;
    boost::mutex mtx;
    work_ptr * work;
    boost::thread_group workers;
};

io_service_processors::io_service_processors(int tc):thread_count(tc) {

}

io_service_processors::~io_service_processors() {
       // clean up code here removed.
}

void io_service_processors::init() {
    this->service = new asio::io_service();
    this->work = new work_ptr(new asio::io_service::work(*(this->service)));
    for(int i = 0; i < this->thread_count; ++i)
        this->workers.create_thread(boost::bind(&asio::io_service::run, this->service));
}

void io_service_processors::post_job(any_job file_job) {
    std::cout << __PRETTY_FUNCTION__ << "\n";
    this->service->post(file_job);
}

struct job_discoverer {

    boost::optional<io_service_processors> processor;

    void process(const fs::path path){
        std::cout << "Posting file: " << path.string() << std::endl;
        if(this->processor)
            this->processor->post_job(
                    boost::bind(&job_discoverer::parse_and_aggregate, this, path)
                    );
    }

    void parse_and_aggregate(const fs::path path) {
        std::cout << "Parsing and aggregating file: " << path.string() << std::endl;
    }
};

int main() {
}