If you have specific questions about the code feel free to ask them! A few general things that might help you to follow the code:
std::thread
is a class wrapping a thread. The constructor of it takes some kind of function object that it should execute on the new thread and optionally some arguments to pass to that function. A very explicit way of doing this might look like that
// the code we want to run on the new thread, wrapped in a free function
void backgroundThreadWork()
{
std::cout << "Hello printed from background thread" << std::endl;
}
// A function to be called from our main code to launch that thread
void launchThread()
{
// We create a thread instance that launches the function above
std::thread backgroundThread (backgroundThreadWork);
// Since we don't want to wait on the thread, we call detach. This will return immediately, so this function doesn't block execution.
// The thread will continue running and do its work, but we loose explicit control about it at this point.
backgroundThread.detach();
}
In my code above, I did some simplifications. First of all, I wrapped the code to be executed into a lambda instead of a function, which works as well. To me, it’s a bit more straightforward to declare
the code to be executed right above the thread instead of putting it in an extra function. The example above, done with a lambda would look like
// A function to be called from our main code to launch that thread
void launchThread()
{
auto backgroundThreadWork = [] ()
{
std::cout << "Hello printed from background thread" << std::endl;
}
// We create a thread instance that launches the lambda declared above
std::thread backgroundThread (backgroundThreadWork);
// Since we don't want to wait on the thread, we call detach. This will return immediately, so this function doesn't block execution.
// The thread will continue running and do its work, but we loose explicit control about it at this point.
backgroundThread.detach();
}
Now we can squeeze it all together a bit. Instead of assigning the lambda to the backgroundThreadWork
variable first and passing it to the thread, we can just put the lambda declaration right into the thread constructor
// A function to be called from our main code to launch that thread
void launchThread()
{
// We create a thread instance that launches the lambda declared in the constructor
std::thread backgroundThread ([] ()
{
std::cout << "Hello printed from background thread" << std::endl;
});
// Since we don't want to wait on the thread, we call detach. This will return immediately, so this function doesn't block execution.
// The thread will continue running and do its work, but we loose explicit control about it at this point.
backgroundThread.detach();
}
Last but not least, we can even avoid creating the named backgroundThread
variable – instead we can call detach
on the newly created thread in place.
// A function to be called from our main code to launch that thread
void launchThread()
{
// We create a thread instance that launches the lambda declared in the constructor and detach it immediately
std::thread backgroundThread ([] ()
{
std::cout << "Hello printed from background thread" << std::endl;
}).detach();
}
Now, in our case we need to get something back from the thread when it’s done. This is done via the std::promise
passed to the thread, which is some storage to write the result to. To access the promise from our main thread, the std::future
object is used, you basically can ask the future if the promised result is ready.
std::async
nicely wraps the thread construction, the promise and the future into a simple call, you put a function/lambda into it and it returns a std::future
wrapping whatever you returns from that function. Internally it will launch the thread for you, creates the promise etc. So you likely want to implement a function that does your sql query, returns a struct with everything that you need and keep a std::future
wrapping that struct as member. That member can be assigned by std::async
.