自动删除发送到异步的容器functions/io_service
Automatically delete containers sent to asynchronous functions/io_service
我想使用 unordered_map 作为作业或会话上下文对象。所以,我想在一些函数中分配它与函数对象中的静态函数捆绑在一起,并将这个函数对象发送到 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
除非你正在实现一个所有权原语(智能 handle/pointer 类型)。具体来说,只需创建一个 pr:
job_processor pr(4);
Same goes for all the members of job_processor
(you were leaking everything, and if job_processor
were copied, you'd get double-free Undefined Behaviour
代码
// pass the reference;
with_static_function::print_map(words);
按值传递...意味着复制整个地图
为了避免复制,修复 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";
}
"heap" 过载可能是,正如我的措辞所暗示的那样,过载。请务必删除无用的重复代码 (!):
static void print_map(map_t const* map) {
if (map) print_map(*map);
}
你甚至不需要那个重载,因为你可以简单地使用 lambda 来绑定(而不是 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); };
完整的工作程序:
#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
我想使用 unordered_map 作为作业或会话上下文对象。所以,我想在一些函数中分配它与函数对象中的静态函数捆绑在一起,并将这个函数对象发送到 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
除非你正在实现一个所有权原语(智能 handle/pointer 类型)。具体来说,只需创建一个 pr:job_processor pr(4);
Same goes for all the members of
job_processor
(you were leaking everything, and ifjob_processor
were copied, you'd get double-free Undefined Behaviour代码
// pass the reference; with_static_function::print_map(words);
按值传递...意味着复制整个地图
为了避免复制,修复
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"; }
"heap" 过载可能是,正如我的措辞所暗示的那样,过载。请务必删除无用的重复代码 (!):
static void print_map(map_t const* map) { if (map) print_map(*map); }
你甚至不需要那个重载,因为你可以简单地使用 lambda 来绑定(而不是
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); };
完整的工作程序:
#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