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.
Related
I have few queries with respect to below code snapshot.
1) With respect to pthread_create(), assume Thread_1 creates Thread_2. To my understanding Thread_1 can exit without join, but still Thread_2 will keep running. Where as in below example without join() I am not able to run thread and I am seeing exceptions.
2) In few examples I am seeing thread creation without thread object as below. But when I do the same, code is terminated.
std::thread(&Task::executeThread, this);
I am compiling with below command.
g++ filename.cpp -std=c++11 -lpthread
But still it terminate with exception. Is this right way of creating thread or is there any different version of C++ (In my project already they are compiling but not sure about the version).
3) In few examples of my project code, I am seeing below way of creating thread. But I am not able to execute with below example.
std::thread( std::bind(&Task::executeThread, this) );
Below is my code snapshot.
#include <iostream>
#include <thread>
class Task
{
public:
void executeThread(void)
{
for(int i = 0; i < 5; i++)
{
std::cout << " :: " << i << std::endl;
}
}
void startThread(void);
};
void Task::startThread(void)
{
std::cout << "\nthis: " << this << std::endl;
#if 1
std::thread th(&Task::executeThread, this);
th.join(); // Without this join() or while(1) loop, thread will terminate
//while(1);
#elif 0
std::thread(&Task::executeThread, this); // Thread creation without thread object
#else
std::thread( std::bind(&Task::executeThread, this) );
while(1);
#endif
}
int main()
{
Task* taskPtr = new Task();
std::cout << "\ntaskPtr: " << taskPtr << std::endl;
taskPtr->startThread();
delete taskPtr;
return 0;
}
Thanks & Regards
Vishnu Beema
std::thread(&Task::executeThread, this); statement creates and destroys a thread object. The destructor of std::thread invokes std::terminate when the thread wasn't joined or detached (like in your statement).
There is no good reason to use std::bind in C++11 because lambdas are better in terms of space and speed.
When building multi-threaded code you need to specify -pthread option when both compiling and linking. Linker option -lpthread is both inadequate and unnecessary.
By design, you need to join all the threads you spawned, or detach them. See e.g. SO question on join/detach
See also cppreference, detach
Note also important caveats if main() exits while detached threads are still running
I also 100% agree with the comment in the other answer about preferring lambdas to bind.
Finally, do not fall for the temptation to do pthread_cancel on a thread in C++. See e.g pthread_cancel considered harmful
In C++ objects have a lifetime. This is a bit different then dealing with handles in C. In C++ if you create an object on the stack in one scope it will be destroyed if you exit that scope. There are some exception to these rule like std::move, but as a rule of thumb you own the lifetime of an object.
This ties into the same answer as above. When you called std::thread(&Task::executeThread, this); you were actually invoking the thread constructor. This is the start of the thread life and the object lifetime. Notice that you created this object on the stack. If you leave the scope { .. yourcode .. } the DTor will be called. Since you have done this before std::move, join or detatch then std::terminate() is called which is raising the exception.
You can create a thread that way. If you look at the linked documentation for std::thread::thread (constructor) there is an example of an object foo being created the same way. What errors are you receiving?
Relevant Documentation:
a. std::thread::~thread()
b. std::thread::thread
c. Lifetime in C++
I personally would recommend understanding the lifetime of objects in a C++. In short all objects start their lifetime when their constructor is invoked. When they are killed (as in out of scope) their destructor is called. The compiler handles this for you so if you're coming from C its a new concept.
Thank you all for your inputs. I missed thread object as part of thread creation. Because of this though compiling, I am getting exceptions. Below is my updated code. All three scenarios are working fine.
#include <iostream>
#include <thread>
class Task
{
public:
void executeThread(std::string command)
{
for(int i = 0; i < 5; i++)
{
std::cout << command << " :: " << i << std::endl;
}
}
void startThread(void);
std::thread th2;
std::thread th3;
};
void Task::startThread(void)
{
std::cout << "\nthis: " << this << std::endl;
#if 0
std::thread th1(&Task::executeThread, this, "Thread1");
th1.join(); // Without join(), thread will terminate
#elif 0
th2 = std::thread(&Task::executeThread, this, "Thread2");
th2.join();
#else
th3 = std::thread( std::bind(&Task::executeThread, this, "Thread3") );
th3.join();
#endif
}
int main()
{
Task* taskPtr = new Task();
std::cout << "\ntaskPtr: " << taskPtr << std::endl;
taskPtr->startThread();
delete taskPtr;
return 0;
}
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;
}
I'm using std::call_once in my code to initialize some shared variables only once. The calling code is inside a callback that is triggered by multiple threads.
What I'm interested to know, since I couldn't find it in the documentation is whether std::call_once is blocking essentially as if there was a std::lock_guard instead?
In practice it looks like this is the case.
For example, the following will print "Done" before any print() will be called:
#include <future>
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void print()
{
for(int i=0;i<10;i++)
{
std::cout << "Hi, my name is " << std::this_thread::get_id()
<< ", what?" << std::endl;
}
}
void do_once()
{
std::cout << "sleeping for a while..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "Done" << std::endl;
}
void work()
{
std::call_once(flag, [](){ do_once(); });
print();
}
int main()
{
auto handle1 = std::async(std::launch::async, work);
auto handle2 = std::async(std::launch::async, work);
auto handle3 = std::async(std::launch::async, work);
auto handle4 = std::async(std::launch::async, work);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
I'm assuming this is indeed the case (since I don't see how it could be implemented otherwise), but is this behavior guaranteed or could there be a compiler that decides that std::call_once will indeed be called once but allow other threads to continue and just ignore this call?
Yes std::call_once is a blocking call. From [thread.once.callonce] we have
Effects: An execution of call_once that does not call its func is a passive execution. An execution of call_once that calls its func is an active execution. An active execution shall call INVOKE (DECAY_COPY ( std::forward<Callable>(func)), DECAY_COPY (std::forward<Args>(args))...). If such a call to func throws an exception the execution is exceptional, otherwise it is returning. An exceptional execution shall propagate the exception to the caller of call_once. Among all executions of call_once for any given once_flag: at most one shall be a returning execution; if there is a returning
execution, it shall be the last active execution; and there are passive executions only if there is a returning execution. [ Note: passive executions allow other threads to reliably observe the results produced by the earlier returning execution. —end note ]
Synchronization: For any given once_flag: all active executions occur in a total order; completion of an active execution synchronizes with (1.10) the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions.
emphasis mine
This means that all calls to call_once will wait until the function passed to call_once completes. In your case that means do_once() must be called before any thread calls print()
#include <future>
#include <iostream>
void main()
{
std::async(std::launch::async,[] {std::cout << "async..." << std::endl; while (1);});
std::cout << "runing main..." << std::endl;
}
In this code, only "async..." will be outputted, which means the code is blocked at async. However, if I add future and let the statement become:
std::future<bool> fut = std::async([]
{std::cout << "async..." << std::endl; while (1); return false; });
Then everything runs smoothly (it will not be blocked). I am not sure why it happen in this way. I think async is supposed to run in a separate thread.
From encppreference.com:
If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code such as the following synchronous:
std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
std::async(std::launch::async, []{ g(); }); // does not start until f() completes
If I did get that right, it comes from these parts of the standard (N4527):
§30.6.6 [futures.unique_future]:
~future();
Effects:
— releases any shared state (30.6.4);
§30.6.4#5 [futures.state] (emphasis is mine):
When an asynchronous return object or an asynchronous provider is said to release its shared state, it means:
[...].
— these actions will not block for the shared state to become ready, except that it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.
Since you did not store the result of your first std::async call, the destructor of std::future is called and since all 3 conditions are met:
the std::future was created via std::async;
the shared state is not yet ready (due to your infinite loop);
there is no remaining reference to this future
...then the call is blocking.
void
set_string(std::promise<std::string>& p)
{
p.set_value("set from thread");
}
int
main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread t(&set_string, std::ref(p));
std::cout << f.get() << std::endl;
t.join();
}
Why do I need to call t.join() after I call f.get()? I thought that f.get() will block the main thread until it can get the result and that would mean that the thread has already finished.
Because even after thread finishes execution it is still joinable. You can call detach to allow independend execution. In this case you might want to use set_value_at_thread_exit member of promise to lessen chance that main finishes before thread:
#include <iostream>
#include <string>
#include <thread>
#include <future>
void set_string(std::promise<std::string>& p)
{
p.set_value_at_thread_exit("set from thread");
}
int main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread(&set_string, std::ref(p)).detach();
std::cout << f.get() << std::endl;
}
http://coliru.stacked-crooked.com/a/1647ffc41e30e5fb
I believe the rationale for threads is simply that you either explicitly join them or that you explicitly detach them, but if a thread object gets destroyed before either happened, you probably have a problem with your design. The decision was not to assume you want to detach it or join it when the destructor is called, because either one is a bad guess in most situations.
Further, concerning your case, it doesn't matter where the future is set from. The requirements for the thread object are not touched by how it triggers the future, they stay the same.
Note that in your case, since you don't care about the thread any longer, you could simply detach it.