main thread waits for std::async to complete [duplicate] - c++

This question already has answers here:
Can I use std::async without waiting for the future limitation?
(5 answers)
Closed 5 years ago.
I am using std::async to create a thread, I want this new thread should execute separately and main thread should not wait for it. But here when I call std::async, a new thread is created but main thread is waiting for completion of fun(). I want main thread to execute parallely without waiting for fun() to complete. How should I do that?
#include <iostream>
#include <windows.h>
#include <future>
using namespace std;
void printid()
{
cout << "Thread id is:" << this_thread::get_id() << endl;
}
void fun(void *obj)
{
cout<<"Entry"<<endl;
printid();
Sleep(10000);
cout<<"Exit"<<endl;
}
int main()
{
cout<<"Hello"<<endl;
printid();
std::async(std::launch::async, fun, nullptr);
cout << "After call" << endl;
}
I am getting output:
Hello
Thread id is:22832
Entry
Thread id is:13156
Exit
After call

A std::future object returned by std::async and launched with std::launch::async policy, blocks on destruction until the task that was launched has completed.
Since you do not store the returned std::future in a variable, it is destroyed at the end of the statement with std::async and as such, main cannot continue until the task is done.
If you store the std::future object, its lifetime will be extended to the end of main and you get the behavior you want.
int main()
{
...
auto fut = std::async(std::launch::async, fun, nullptr);
...
}

std::async(std::launch::async, fun, nullptr);
Doesn't do anything with the returned std::future, leaving it to be destroyed. That's a problem because std::future's destructor may block and wait for the thread to finish.
The solution is to hold on to the std::future for a while and let it be destroyed after you're done with everything else.
auto locallyScopedVariable = std::async(std::launch::async, fun, nullptr);
locallyScopedVariable will go out of scope at the end of main and then block until it completes.
Note that this still might not do quite what you want. The main thread could immediately yield the processor to the new thread and allow the new thread to run to completion before control is returned. The code can be corrected and still result in the output of the incorrect version.

(1) In multi-threading program testing, protect shared resource (cout in this case) from being invoked from different threads at same time using a mutex.
(2) Check if future is ready in the main, you can do a timeout also.
void print_id()
{
lock_guard<mutex> locker(mutex_);
cout << "Thread id is:" << this_thread::get_id() << endl;
}
void print( string str)
{
lock_guard<mutex> locker(mutex_);
cout << str << '\n';
}
bool fun(void *obj)
{
print("Entry");
printid();
Sleep(10000);
print("Exit");
return true;
}
int main()
{
print("Hello");
printid();
std::future<bool> fut = std::async(std::launch::async, fun,nullptr);
while(!fut->_Is_ready() )
{
}
cout << "After call" << endl;
}

Related

How can I syncronize these two threads properly?

I would like to synchronize different threads properly but so far I have only be able to write an inelegant solution. Can somebody kindly point out how I can improve the following code?
typedef void (*func)();
void thread(func func1, func func2, int& has_finished, int& id) {
has_finished--;
func1();
has_finished++;
while (has_finished != 0) std::cout << "thread " << id << " waiting\n";
std::cout << "thread" << id << "resuming\n";
func2();
}
int main() {
int has_finished(0), id_one(0), id_two(1);
std::thread t1(thread, fun, fun, std::ref(has_finished), std::ref(id_one));
std::thread t2(thread, fun, fun, std::ref(has_finished), std::ref(id_two));
t1.join();
t2.join();
};
The gist of the program is described by the function thread. The function is executed by two std::threads. The function accepts two long-running functions func1 and func2 and two references of ints as arguments. The threads should only invoke func2 after all threads exited func1. The argument has_finished is used to coordinate the different threads: Upon entering the function, has_arguments is zero. Then each std::thread decrements the value and invokes the long-running function func1. After having left func1, has_finished is incremented again. As long as this value is not at its original value of zero a thread waits. Then, each thread works on func2. The main function is shown at the end.
How can I coordinate the two threads better? I was thinking of using a std::mutex and std::condition_variable but could not figure out how to use them properly? Does somebody have any idea how I can improve the program?
Don't write this yourself. This kind of synchronization is known as a "latch" (or more generally a "barrier", and it's available through various libraries and through the C++ Concurrency TS. (It might also make it into C++20 in some form.)
For example, using a version from Boost:
#include <iostream>
#include <thread>
#include <boost/thread/latch.hpp>
void f(boost::latch& c) {
std::cout << "Doing work in round 1\n";
c.count_down_and_wait();
std::cout << "Doing work in round 2\n";
}
int main() {
boost::latch c(2);
std::thread t1(f, std::ref(c)), t2(f, std::ref(c));
t1.join();
t2.join();
}
The method you've chosen won't actually work and results in undefined behavior because of the race conditions. As you surmised, you need a condition variable.
Here is a Gate class demonstrating how to use a condition variable to implement a gate that waits for some number of threads to arrive at it before continuing:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <sstream>
#include <utility>
#include <cassert>
struct Gate {
public:
explicit Gate(unsigned int count = 2) : count_(count) { } // How many threads need to reach the gate before it unlocks
Gate(Gate const &) = delete;
void operator =(Gate const &) = delete;
void wait_for_gate();
private:
int count_;
::std::mutex count_mutex_;
::std::condition_variable count_gate_;
};
void Gate::wait_for_gate()
{
::std::unique_lock<::std::mutex> guard(count_mutex_);
assert(count > 0); // Count being 0 here indicates an irrecoverable programming error.
--count_;
count_gate_.wait(guard, [this](){ return this-> count_ <= 0; });
guard.unlock();
count_gate_.notify_all();
}
void f1()
{
::std::ostringstream msg;
msg << "In f1 with thread " << ::std::this_thread::get_id() << '\n';
::std::cout << msg.str();
}
void f2()
{
::std::ostringstream msg;
msg << "In f2 with thread " << ::std::this_thread::get_id() << '\n';
::std::cout << msg.str();
}
void thread_func(Gate &gate)
{
f1();
gate.wait_for_gate();
f2();
}
int main()
{
Gate gate;
::std::thread t1{thread_func, ::std::ref(gate)};
::std::thread t2{thread_func, ::std::ref(gate)};
t1.join();
t2.join();
}
Hopefully the structure of this code looks enough like your code that you can understand what's going on here. From reading your code, it seems like you're looking for all threads to execute func1, then func2. You do not want func2 running while any thread is executing func1.
That can be thought of as a gate where all the threads are waiting to arrive at the 'finished func1' location before moving on to run func2.
I tested this code on my own local version of compiler explorer.
The main disadvantage of the latch in the other answer is that it is not yet standard C++. My Gate class is a simple implementation of the latch class mentioned in the other answer, and it is standard C++.
The basic way a condition variable works is that it unlocks a mutex, waits for a notify, then locks that mutex and tests the condition. If the condition is true, it continues without unlocking the mutex. If the condition is false, it starts over again.
So, after the condition variable says the condition is true, you have to do whatever you need to do, then unlock the mutex and notify everybody that you've done it.
The mutex here is guarding the shared count variable. Whenever you have a shared value you should guard it with a mutex so that no thread can see that value in an inconsistent state. The condition is that threads can wait for that count to reach 0, indicating that all threads have decremented the count variable.

C++: Is a mutex with `std::lock_guard` enough to synchronize two `std::thread`s?

My question is based on below sample of C++ code
#include <chrono>
#include <thread>
#include <mutex>
#include <iostream>
class ClassUtility
{
public:
ClassUtility() {}
~ClassUtility() {}
void do_something() {
std::cout << "do something called" << std::endl;
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
}
};
int main (int argc, const char* argv[]) {
ClassUtility g_common_object;
std::mutex g_mutex;
std::thread worker_thread_1([&](){
std::cout << "worker_thread_1 started" << std::endl;
for (;;) {
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "worker_thread_1 looping" << std::endl;
g_common_object.do_something();
}
});
std::thread worker_thread_2([&](){
std::cout << "worker_thread_2 started" << std::endl;
for (;;) {
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "worker_thread_2 looping" << std::endl;
g_common_object.do_something();
}
});
worker_thread_1.join();
worker_thread_2.join();
return 0;
}
This is more of a question to get my understanding clear rather & get a sample usage of std::condition_variable iff required.
I have 2 C++ std::threads which start up in main method. Its a console app on osx. So compiling it using clang. Both the threads use a common object of
ClassUtility to call a method do some heavy task. For this sample code to explain the situation, both the threads run an infinite loop & close down only when
the app closes i.e. when I press ctrl+c on the console.
Seek to know:
Is it correct if I jus use a std::lock_guard on std::mutex to synchronize or protect the calls made to the common_obejct of ClassUtility. Somehow, I seem
to be getting into trouble with this "just a mutex approach". None of the threads start if I lock gaurd the loops using mutex. Moreover, I get segfaults sometimes. Is this because they are lambdas ?
assigned to each thread ?
Is it better to use a std::condition_variable between the 2 threads or lambdas to signal & synchronize them ? If yes, then how would the std::condition_variable be used
here between the lambdas ?
Note: As the question is only to seek information, hence the code provided here might not compile. It is just to provide a real scenario
Your code is safe
Remember, the lock_guard just calls .lock() and injects call to .unlock() to the end of the block. So
{
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "worker_thread_1 looping" << std::endl;
g_common_object.do_something();
}
is basically equivalent to:
{
g_mutex.lock();
std::cout << "worker_thread_1 looping" << std::endl;
g_common_object.do_something();
g_mutex.unlock();
}
except:
the unlock is called even if the block is left via exception and
it ensures you won't forget to call it.
Your code is not parallel
You are mutually excluding all of the loop body in each thread. There is nothing left that both threads could be actually doing in parallel. The main point of using threads is when each can work on separate set of objects (and only read common objects), so they don't have to be locked.
In the example code, you really should be locking only the work on common object; std::cout is thread-safe on it's own. So:
{
std::cout << "worker_thread_1 looping" << std::endl;
{
std::lock_guard<std::mutex> lock(g_mutex);
g_common_object.do_something();
// unlocks here, because lock_guard injects unlock at the end of innermost scope.
}
}
I suppose the actual code you are trying to write does have something to actually do in parallel; just a thing to keep in mind.
Condition variables are not needed
Condition variables are for when you need one thread to wait until another thread does some specific thing. Here you are just making sure the two threads are not modifying the object at the same time and for that mutex is sufficient and appropriate.
Your code never terminates other than that I can't fault it.
As others point out it offers almost not opportunity for parallelism because of the long sleep that takes place with the mutex locked to sleeping thread.
Here's a simple version that terminates by putting arbitrary finite limits on the loops.
Is it maybe that you haven't understood what join() does?
It the current thread (executing join()) until the joined thread ends. But if it doesn't end neither does the current thread.
#include <chrono>
#include <thread>
#include <mutex>
#include <iostream>
class ClassUtility
{
public:
ClassUtility() {}
~ClassUtility() {}
void do_something() {
std::cout << "do something called" << std::endl;
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
}
};
int main (int argc, const char* argv[]) {
ClassUtility g_common_object;
std::mutex g_mutex;
std::thread worker_thread_1([&](){
std::cout << "worker_thread_1 started" << std::endl;
for (int i=0;i<10;++i) {
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "worker_thread_1 looping " << i << std::endl;
g_common_object.do_something();
}
});
std::thread worker_thread_2([&](){
std::cout << "worker_thread_2 started" << std::endl;
for (int i=0;i<10;++i) {
std::lock_guard<std::mutex> lock(g_mutex);
std::cout << "worker_thread_2 looping " << i << std::endl;
g_common_object.do_something();
}
});
worker_thread_1.join();
worker_thread_2.join();
return 0;
}

Parent thread join(): Blocks Until Children Finish?

I have a C++ class that does some multi-threading. Consider the pseudo-code below:
void MyClass::Open() {
loop_flag = true;
// create consumer_thread (infinite loop)
// create producer_thread (infinite loop)
}
void MyClass::Close() {
loop_flag = false;
// join producer_thread
// join consumer_thread
}
MyClass::~MyClass() {
Close();
// do other stuff here
}
Note that consumer_thread, producer_thread, and their associated functions are all encapsulated in MyClass. The caller has no clue that their calls are multi-threaded and what's going on in the background.
Now, the class is part of a larger program. The program has some initial multi-threading to handle configuration of the system since there's a ton of stuff happening at once.
Like this (pseudo-code):
int main() {
// create config_thread1 (unrelated to MyClass)
// create thread for MyClass::Open()
// ...
// join all spawned configuration threads
}
So my question is, when I call join() for the thread linked to MyClass::Open() (i.e., the configuration thread spawned in main()), what happens? Does it join() immediately (since the MyClass::Open() function just returns after creation of producer_thread and consumer_thread) or does it wait for producer_thread and consumer_thread to finish (and therefore hangs my program).
Thanks in advance for the help. In terms of implementation details, I'm using Boost threads on a Linux box.
Edited to add this diagram:
main()
|
|
|
|--->configuration_thread (that runs MyClass::Open())
|
|
|----> producer_thread
|----> consumer_thread
If I call join() on configuration_thread(), does it wait until producer_thread() and consumer_thread() are finished or does it return immediately (and producer_thread() and consumer_thread() continue to run)?
A (non detached) thread will be joignable, even after having returned from the function it was set to run, until it has been joined.
Example:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void foo(){
std::cout << "helper: I'm done\n";
}
int main(){
cout << "starting helper...\n";
thread helper(foo);
this::thread::sleep_for(std::chrono::seconds(5));
cout << "helper still joignable?..." << (helper.joignable()?"yes!":"no...:(") << "\n";
helper.join();
cout << "helper joined!";
cout << "helper still joignable?..." << (helper.joignable()?"really?":"not anymore!") << "\n";
cout << "done!\n";
}
Output:
starting helper...
helper: I'm done
still joinable?...yes!
helper joined!
still joinable?...not anymore!
done!
As for how much time the join method takes, I don't think this is specified, but surely it doesn't't have to wait for all the other threads to finish, or it would mean that only one thread would be able to join all the others.
From §30.3.5:
void Join();
Requires: joinable() is true
Effects: Blocks until the thread represented by *this had completed.
Synchronization: The completion of the thread represented by *this synchronises with the corresponding successful join() return. [Note: Operations on *this are not synchronised. * -- end note*]
[...]

C++ std::async run on main thread

IS there a way of running a function back on the main thread ?
So if I called a function via Async that downloaded a file and then parsed the data. It would then call a callback function which would run on my main UI thread and update the UI ?
I know threads are equal in the default C++ implementation so would I have to create a shared pointer to my main thread. How would I do this and pass the Async function not only the shared pointer to the main thread but also a pointer to the function I want to rrun on it and then run it on that main thread ?
I have been reading C++ Concurrency in Action and chapter four (AKA "The Chapter I Just Finished") describes a solution.
The Short Version
Have a shared std::deque<std::packaged_task<void()>> (or a similar sort of message/task queue). Your std::async-launched functions can push tasks to the queue, and your GUI thread can process them during its loop.
There Isn't Really a Long Version, but Here Is an Example
Shared Data
std::deque<std::packaged_task<void()>> tasks;
std::mutex tasks_mutex;
std::atomic<bool> gui_running;
The std::async Function
void one_off()
{
std::packaged_task<void()> task(FUNCTION TO RUN ON GUI THREAD); //!!
std::future<void> result = task.get_future();
{
std::lock_guard<std::mutex> lock(tasks_mutex);
tasks.push_back(std::move(task));
}
// wait on result
result.get();
}
The GUI Thread
void gui_thread()
{
while (gui_running) {
// process messages
{
std::unique_lock<std::mutex> lock(tasks_mutex);
while (!tasks.empty()) {
auto task(std::move(tasks.front()));
tasks.pop_front();
// unlock during the task
lock.unlock();
task();
lock.lock();
}
}
// "do gui work"
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
Notes:
I am (always) learning, so there is a decent chance that my code is not great. The concept is at least sound though.
The destructor of the return value from std::async (a std::future<>) will block until the operation launched with std::async completes (see std::async ), so waiting on the result of a task (as I do in my example) in one_off might not be a brilliant idea.
You may want to (I would, at least) create your own threadsafe MessageQueue type to improve code readability/maintainability/blah blah blah.
I swear there was one more thing I wanted to point out, but it escapes me right now.
Full Example
#include <atomic>
#include <chrono>
#include <deque>
#include <iostream>
#include <mutex>
#include <future>
#include <thread>
// shared stuff:
std::deque<std::packaged_task<void()>> tasks;
std::mutex tasks_mutex;
std::atomic<bool> gui_running;
void message()
{
std::cout << std::this_thread::get_id() << std::endl;
}
void one_off()
{
std::packaged_task<void()> task(message);
std::future<void> result = task.get_future();
{
std::lock_guard<std::mutex> lock(tasks_mutex);
tasks.push_back(std::move(task));
}
// wait on result
result.get();
}
void gui_thread()
{
std::cout << "gui thread: "; message();
while (gui_running) {
// process messages
{
std::unique_lock<std::mutex> lock(tasks_mutex);
while (!tasks.empty()) {
auto task(std::move(tasks.front()));
tasks.pop_front();
// unlock during the task
lock.unlock();
task();
lock.lock();
}
}
// "do gui work"
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main()
{
gui_running = true;
std::cout << "main thread: "; message();
std::thread gt(gui_thread);
for (unsigned i = 0; i < 5; ++i) {
// note:
// these will be launched sequentially because result's
// destructor will block until one_off completes
auto result = std::async(std::launch::async, one_off);
// maybe do something with result if it is not void
}
// the for loop will not complete until all the tasks have been
// processed by gui_thread
// ...
// cleanup
gui_running = false;
gt.join();
}
Dat Output
$ ./messages
main thread: 140299226687296
gui thread: 140299210073856
140299210073856
140299210073856
140299210073856
140299210073856
140299210073856
Are you looking for std::launch::deferred ? Passing this parameter to std::async makes the task executed on the calling thread when the get() function is called for the first time.

the behavior of std::async with std::launch::async policy

I have some question about behavior of std::async function with std::launch::async policy & std::future object returned from async.
In following code, main thread waits for the completion of foo() on the thread created by async call.
#include <thread>
#include <future>
#include <iostream>
void foo()
{
std::cout << "foo:begin" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "foo:done" << std::endl;
}
int main()
{
std::cout << "main:begin" << std::endl;
{
auto f = std::async(std::launch::async, foo);
// dtor f::~f blocks until completion of foo()... why??
}
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "main:done" << std::endl;
}
And I know http://www.stdthread.co.uk/doc/headers/future/async.html says
The destructor of the last future object associated with the
asynchronous state of the returned std::future shall block until the
future is ready.
My question is:
Q1. Does this behavior conform to the current C++ standard?
Q2. If Q1's answer is yes, which statements say that?
Yes, this is required by the C++ Standard. 30.6.8 [futures.async] paragraph 5, final bullet:
— the associated thread completion synchronizes with (1.10) the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.
The destructor of the one and only std:future satisfies that condition, and so has to wait for the completion of the thread.