Corelink CPP Client
Corelink C++ client library
 
Loading...
Searching...
No Matches
Key Concepts

Notes

‍These documents are a work in progress, and we are trying to improve upon them on a daily basis. However, given our capacity and workload, there are bound to be things which get missed or checked in which should not have been checked in. If you find mistakes or documents wanting information, and you would like to help, you can do so in two ways

  1. Submit corrections. When you update anything and submit a PR, we will review it and if all looks good, it will be added. This is the fastest way that one can expect changes to be in.
  2. Submit tickets. If you are not sure how to make updates, or if you are short on time, please raise an issue in the repo, with details and what you think needs to be the expected text. We will try and update the literature to reflect any changes that we feel are merited. Note that this route will take longer than the first approach and there are no guarantees on the timeline.

Non-blocking functions

To explain the concept of a non-blocking function, we will use two example functions foo() and bar().

Say foo() waits for 5 seconds then prints "foo", and bar() simply prints "bar".

We run the following:

int main()
{
foo();
bar();
return 0;
}

If foo() is a blocking (synchronous/standard) function, our output will be:

"foo"
"bar"

If foo() is a non-blocking (asynchronous) function, our output will be:

"bar"
"foo"

In the case of a non-blocking function, since foo() doesn't stop the program from moving forward, you might wonder how you can actually know when it's done. That's where callbacks come in.

To get the result of what foo() is doing, you need to give the library a way to notify you when the operation completes.

This is called setting up a hook. When foo() finishes its work, it will "call you back" by running a function you provided, known as a callback function.

This way, your program can keep doing other tasks, and once foo() is done, your callback function gets executed to handle the result or next steps.

std::async

In the Corelink C++ Client, we use the std::future class template and std::async function template to achieve asynchronous, non-blocking function behavior.

When using std::async, you can run foo() asynchronously, meaning that it will execute in the background without blocking the rest of your program. std::async effectively launches foo() in a separate thread, so your main program can continue running and, for example, proceed to execute bar() immediately.

Here’s how std::async can help with non-blocking behavior:

#include <iostream>
#include <future>
void foo() {
std::this_thread::sleep_for(std::chrono::seconds(5)); // Simulates a long operation
std::cout << "foo" << std::endl;
}
void bar() {
std::cout << "bar" << std::endl;
}
int main() {
// Launch foo asynchronously
std::future<void> result = std::async(std::launch::async, foo);
// Execute bar immediately without waiting for foo to finish
bar();
// Optionally wait for foo to finish (if needed for the result)
result.get();
return 0;
}

In this example, std::async runs foo() asynchronously, so bar() gets executed right after launching foo(), resulting in the output:

"bar"
"foo"

The std::future returned by std::async lets you optionally check or wait for the result of foo() later.

This is a key difference from traditional callbacks: instead of providing a callback directly, you can use the std::future to retrieve the result when needed. This gives more flexibility in how you handle non-blocking operations, while still avoiding blocking the main program flow.