3

I have written a small synchronous C++ application. I've reached the point where I need to call some API that runs asynchronously, calling some registered callback when a result is available. The problem I'm having is that the synchronous part is dependant of the result coming from the asynchronous call.

What is the best recommended method to use when mixing synchronous and asynchronous code ?

To explain it further. I would like to call the async api, catch the result and from there continue with the code in my main(...).

Any suggestions are helpful.

I've been looking at maybe using a state machine. Is this recommended ?

4
  • You must stop your syncronous thread and wait for asyncronous thread to finish, in windows you could use EnterCriticalSection & co. Commented Mar 15, 2016 at 22:18
  • 2
    Sounds like you want to wait on a std::future/promise? Commented Mar 15, 2016 at 22:19
  • What you state is a bit contradictory. You say you need the result of an asynchronous computation, but you need it synchronously...! Commented Mar 15, 2016 at 22:22
  • You can either block then and there until the result is available, or if the API allows it, put the rest of what you need to do in the callback. Commented Mar 15, 2016 at 22:22

3 Answers 3

4

If you are using some third party API that already implements asyncronous jobs then all you have to do is just to follow their rules. New C++11 async thread stuff such as std::future/std::promise won't help because you don't need to invoke your own tasks in separate thread, but what you need is to work with the result that you receive asynchronously provided back by that API to your current thread.

If the API doesn't have a synchronous option of operating then you have to work with it in asynchronous way. When you reach the point where you make the async call and if you need there a result to continue your work then all you can do is put your callback handler as a callback parameter to that API async call. In C++11 you can use a lambda as the callback handler. In this case you'll just have to cut-and-paste the code into the lambda from below of the API call when it used to be synchronous.

And some event loop provided by that async API must be running infinitely somewhere to ensure that your working thread is alive and can invoke asynchronous callbacks. For example, in boost::asio it is io_service.run() and the callbacks are being posted back to your working thread via io_service.post(callback).

See example below.

// legacy code when you worked with sync API
void syncProcess()
{
   // code before call

   ResultType callResult=syncAPI.call(args);

   // code after call
}

// now you have async API
void asyncProcess()
{
   // code before call

   asyncAPI.call(args,
        [=](ResultType callResult)
        {
           // code after call
        }
   );

   /* the event loop can be here
    for example, it can be boost::asio::io_service::run() in case you're using boost::asio
   or something similar that keeps your main working thread alive and not locked
    if you use third party async API it must provide the event loop where async callbacks are invoked
  */
}
Sign up to request clarification or add additional context in comments.

Comments

2

I think that futures best fit your needs. Check cplusplus.com for further information. If you need some code examples, do not hesitate to ask in the comments.

Comments

2

I would create a condition variable and an atomic bool. Do the API-call and check for the bool to be true (if so than you can't wait for notification) and if not, wait for the condition variable. In the callback you must set the bool and notify the condition variable.

Waiting for the condition variable also need a mutex of course.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.