我想将unordered_map用作作业或 session 上下文对象。因此,我想在某个功能束中将其与功能对象中的静态功能一起分配,然后将此功能对象发送至io_service。显然,我不用担心分配它。

关于如何做到这一点的任何想法?

谢谢!

#include <iostream>
#include <unordered_map>
#include "boost/asio.hpp"
#include "boost/thread.hpp"

using namespace std;
namespace asio = boost::asio;

typedef std::unique_ptr<asio::io_service::work> work_ptr;
typedef boost::function<void(void) > boost_void_void_fun;

class job_processor {
public:

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

    void post_task(boost_void_void_fun job) {
        this->service->post(job);
    }

    void drain() {
        this->work->reset();
    }

    void wait() {
        this->workers.join_all();
    }
private:
    int thread_count;
    work_ptr * work;
    asio::io_service* service;
    boost::thread_group workers;
};

typedef std::unordered_map<string, unsigned long> map_t;

class with_static_function {
public:

    static void print_map(map_t map) {
        for(map_t::iterator it = map.begin(); it != map.end(); ++it)
            std::cout << it->first << ":" << it->second << std::endl;
    }

    static void print__heap_map(map_t* map) {
        if(!map) return;
        for(map_t::iterator it = map->begin(); it != map->end(); ++it)
            std::cout << it->first << ":" << it->second << std::endl;
    }
};

int main(int argc, char** argv) {
    map_t words;
    words["one"] = 1;

    // pass the reference;
    with_static_function::print_map(words);
    job_processor *pr = new job_processor(4);
    {
        map_t* heap_map = new map_t;
        (*heap_map)["two"] = 2;
        // I need this variable to the job_processor;
        // and I do not want to worry about deallocation.
        // should happen automatically somehow.
        // I am ok with changing the variable to be a shared_ptr or
        // anything else that works.
        boost_void_void_fun fun = boost::bind(
                &with_static_function::print__heap_map,
                heap_map);
        fun(); // if binding was done right this should have worked.
        pr->post_task(fun);
    }

    pr->drain();
    pr->wait();

    delete pr;

    return 0;
}

最佳答案

一些观察:

  • 停止模拟Java 。除非您要实现所有权原语(智能句柄/指针类型),否则请勿使用new。具体来说,只需创建一个PR:
    job_processor pr(4);
    

  • 代码
    // pass the reference;
    with_static_function::print_map(words);
    

    按值传递...表示整个 map 已复制
  • 为避免该副本,请修复print_map签名:
    static void print_map(map_t const& map) {
        for(map_t::const_iterator it = map.begin(); it != map.end(); ++it)
            std::cout << it->first << ":" << it->second << std::endl;
    }
    

    当然,考虑写
    static void print_map(map_t const& map) {
        for(auto& e : map)
            std::cout << e.first << ":" << e.second << "\n";
    }
    
  • 就像我的措辞所暗示的那样,它的“堆”重载可能是一个重载。确保删除无用的重复代码(!):
    static void print_map(map_t const* map) {
        if (map) print_map(*map);
    }
    
  • 您甚至不需要重载,因为您可以简单地使用lambda进行绑定(bind)(而不是boost::bind):
    auto heap_map = boost::make_shared<map_t>();
    heap_map->insert({{"two", 2}, {"three", 3}});
    
    boost_void_void_fun fun = [heap_map] { with_static_function::print_map(*heap_map); };
    

  • 完整的工作程序:

    Live On Coliru
    #include <iostream>
    #include <unordered_map>
    #include <boost/asio.hpp>
    #include <boost/make_shared.hpp>
    #include <boost/thread.hpp>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    
    namespace asio = boost::asio;
    
    typedef boost::function<void(void)> boost_void_void_fun;
    
    class job_processor {
    public:
    
        job_processor(int threads) : service(), work(boost::asio::io_service::work(service))
        {
            for (int i = 0; i < threads; ++i)
                workers.create_thread(boost::bind(&asio::io_service::run, &service));
        }
    
        void post_task(boost_void_void_fun job) {
            service.post(job);
        }
    
        void drain() {
            work.reset();
        }
    
        void wait() {
            workers.join_all();
        }
    private:
        asio::io_service service;
        boost::optional<asio::io_service::work> work;
        boost::thread_group workers;
    };
    
    typedef std::unordered_map<std::string, unsigned long> map_t;
    
    namespace with_static_function {
        static void print_map(map_t const& map) {
            for(auto& e : map)
                std::cout << e.first << ":" << e.second << "\n";
        }
    }
    
    int main() {
        // pass the reference;
        with_static_function::print_map({ { "one", 1 } });
    
        job_processor pr(4);
        {
            auto heap_map = boost::make_shared<map_t>();
            heap_map->insert({{"two", 2}, {"three", 3}});
    
            boost_void_void_fun fun = [heap_map] { with_static_function::print_map(*heap_map); };
            pr.post_task(fun);
        }
    
        pr.drain();
        pr.wait();
    }
    

    版画
    one:1
    three:3
    two:2
    

    关于c++ - 自动删除发送给异步函数/io_service的容器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32335154/

    10-11 22:57
    查看更多