模式的未来转换

编程入门 行业动态 更新时间:2024-10-12 22:25:49
本文介绍了模式的未来转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

目前,我们正在使用异步值非常沉重。假设我有一个函数,确实是这样的:

currently we are using asynchronous values very heavily. Assume that I have a function which does something like this:

int do_something(const boost::posix_time::time_duration& sleep_time) { BOOST_MESSAGE("Sleeping a bit"); boost::this_thread::sleep(sleep_time); BOOST_MESSAGE("Finished taking a nap"); return 42; }

在code某个时刻,我们创造它创建了一个未来将由一个packaged_task设置这样一个int值的任务 - (worker_queue是一个boost :: ASIO :: io_service对象在这个例子中)是这样的:

At some point in code we create a task which creates a future to such an int value which will be set by a packaged_task - like this (worker_queue is a boost::asio::io_service in this example):

boost::unique_future<int> createAsynchronousValue(const boost::posix_time::seconds& sleep) { boost::shared_ptr< boost::packaged_task<int> > task( new boost::packaged_task<int>(boost::bind(do_something, sleep))); boost::unique_future<int> ret = task->get_future(); // Trigger execution working_queue.post(boost::bind(&boost::packaged_task<int>::operator (), task)); return boost::move(ret); }

在code还有一点我想换这个函数返回一些更高级别的对象,它也应该是未来。我需要一个转换函数,它接受的第一个值,并将其转换为另一个值(在我们的实际code,我们有一定的层次感,做异步RPC返回期货的反应 - 这些反应应转换为期货实物,吊舱甚至无效的将来能够在其上等待或捕获异常)。因此,这是在本实施例的转换功能:

At another point in code I want to wrap this function to return some higher level object which should also be a future. I need a conversion function which takes the first value and transforms it to another value (in our actual code we have some layering and doing asynchronous RPC which returns futures to responses - these responses should be converted to futures to real objects, PODs or even void future to be able to wait on it or catch exceptions). So this is the conversion function in this example:

float converter(boost::shared_future<int> value) { BOOST_MESSAGE("Converting value " << value.get()); return 1.0f * value.get(); }

这时我想作为升压文档描述只做如果想这种转换创建一个懒惰的未来:

Then I thought of creating a lazy future as described in the Boost docs to do this conversion only if wanted:

void invoke_lazy_task(boost::packaged_task<float>& task) { try { task(); } catch(boost::task_already_started&) {} }

然后,我有一个函数(可能是更高层次的API)来创建一个包裹的未来:

And then I have a function (might be a higher level API) to create a wrapped future:

boost::unique_future<float> createWrappedFuture(const boost::posix_time::seconds& sleep) { boost::shared_future<int> int_future(createAsynchronousValue(sleep)); BOOST_MESSAGE("Creating converter task"); boost::packaged_task<float> wrapper(boost::bind(converter, int_future)); BOOST_MESSAGE("Setting wait callback"); wrapper.set_wait_callback(invoke_lazy_task); BOOST_MESSAGE("Creating future to converter task"); boost::unique_future<float> future = wrapper.get_future(); BOOST_MESSAGE("Returning the future"); return boost::move(future); }

最后我希望能够用这样的:

At the end I want to be able to use it like this:

{ boost::unique_future<float> future = createWrappedFuture(boost::posix_time::seconds(1)); BOOST_MESSAGE("Waiting for the future"); future.wait(); BOOST_CHECK_EQUAL(future.get(), 42.0f); }

但在这里我最终得到约一个破碎的承诺例外。究其原因似乎是pretty明确对我来说,因为它执行转换packaged_task超出范围。

But here I end up getting an exception about a broken promise. The reason seems to be pretty clear for me because the packaged_task which does the conversion goes out of scope.

所以我的追问是:我该如何处理这种情况。我怎样才能prevent被破坏的任务吗?有没有一种模式,这?

So my questing is: How do I deal with such situations. How can I prevent the task from being destroyed? Is there a pattern for this?

最好成绩,

罗尼

推荐答案

您需要妥善管理任务对象的生命周期。

You need to manage the lifetime of task object properly.

最正确的方法是返回的boost :: packaged_task&LT;浮动&GT; 而不是的boost :: unique_future&LT;浮动&GT; 从 createWrappedFuture()。主叫方将负责未来获取对象和prolongate任务生命周期,直到未来的价值已准备就绪。

The most correct way is to return boost::packaged_task<float> instead of boost::unique_future<float> from createWrappedFuture(). The caller will be responsible to get future object and to prolongate task lifetime until future value is ready.

或者你可以把任务对象为一些悬而未决的队列(全局或类成员)您在 createAsynchronousValue 也进行了类似的方式。但在这种情况下,你将需要explcitly管理任务的一生,完成后从队列中删除。所以不要以为这种解决方案具有的优势对返回任务,对象本身。

Or you can place task object into some 'pending' queue (global or class member) the similar way you did in createAsynchronousValue. But in this case you will need to explcitly manage task lifetime and remove it from queue after completion. So don't think this solution has advantages against returning task object itself.

更多推荐

模式的未来转换

本文发布于:2023-11-25 02:29:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1627957.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   未来

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!