현재 비동기 값을 매우 많이 사용하고 있습니다. 이 같은 (WORKER_QUEUE을 - 우리는 packaged_task에 의해 설정 될 것 같은 int 값에 미래를 만드는 작업을 생성 코드에서 어떤 시점에서향후 변환을위한 패턴
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;
}
: 내가 이런 일을하는 기능을 가지고 있다고 가정
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);
}
코드의 다른 지점에서 나는 또한 앞으로해야합니다 몇 가지 높은 수준의 객체를 반환하기 위해이 기능을 포장 할 : 부스트 ::이 예에서는 ASIO :: io_service)입니다. 첫 번째 값을 가져 와서 다른 값으로 변환하는 변환 함수가 필요합니다. 실제 코드에서는 레이어를 만들고 응답에 미래를 반환하는 비동기 RPC를 수행합니다.이 응답은 실제 개체, POD 또는 무효로 변환되어야합니다. 그것을 기다리거나 예외를 잡을 수있는 미래). 그때가
void invoke_lazy_task(boost::packaged_task<float>& task)
{
try
{
task();
}
catch(boost::task_already_started&)
{}
}
그리고 :
float converter(boost::shared_future<int> value)
{
BOOST_MESSAGE("Converting value " << value.get());
return 1.0f * value.get();
}
그럼 내가 원하는 경우에만이 변환을 수행 할 부스트 문서에 설명 된대로 게으른 미래를 만드는 생각 : 그래서 이것은이 예에서 변환 기능입니다 나는이 같이 사용할 수 있도록하려면 끝에서
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);
}
: 함수는 포장 미래를 창조하는 (높은 수준의 API 수 있습니다)
{
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);
}
하지만 여기에서는 끝내주는 약속에 대한 예외가 발생합니다. 그 이유는 변환 작업을 수행하는 packaged_task가 범위를 벗어나기 때문에 나에게 꽤 분명해 보입니다.
내 탐구는 다음과 같습니다. 어떻게 이런 상황을 처리합니까? 작업이 파괴되지 않게하려면 어떻게합니까? 이 패턴이 있습니까?
Bests,
로니
나는 boost :: ... future와 동일한 인터페이스를 제공하는 자신 만의 클래스를 만들려고 생각했다.이 인터페이스는 태스크를 보유하고 미래의 모든 인터페이스 호출을 위임한다. 그러나 더 나은 해결책이 있어야합니다. – duselbaer
작업이 호출 될 때 변환이 수행되도록 평가중인 함수를 래핑 할 수없는 이유가 있습니까? –
@DaveS 주요 문제는 이러한 기능이 소프트웨어의 다른 계층의 일부라는 것입니다. createAsynchronousValue 메서드는 RPC 메시징 계층에서 관리하는 RPC 요청에 해당합니다. 나는 그것에 대해 생각합니다 ...:) – duselbaer