Waiting for a thread to finish and future - c++

Having such simple code:
void func(std::promise<int>* p) {
int a = 10, b = 5;
int result = a + b;
std::cout << "From inside the Thread...." << std::endl;
p->set_value(result);
}
int FP_main() {
std::promise<int> p;
std::future<int> f = p.get_future();
std::thread th(func, &p);
int ret = f.get();
std::cout << "returned val: " << ret << std::endl;
th.join();
return 0;
}
Why do we need the join function call if there is get call just 2 lines above? Isn't the get function waiting for a thread to finish?

Because the thread is not the promise.
Promise is finished, but thread is not.
p->set_value(result);
// ...
// HERE
// ...
}
That are the last lines of func. The thread will now do its cleanups, will call destructors, etc. All while the promise is finished. Of couse, in 'HERE' the thread may a ton of other work - you can write a 1-hour long task in HERE to keep the thread alive and it will have nothing to do with the promise.
That's probably all clear already.
The last interesting bit is here:
int FP_main() {
//...
std::thread th(func, &p);
//...
th.join();
return 0;
}
The 'th' is a local variable. When the main() returns, the destructor of th will be invoked. And that destructor throws an exception when the thread in question is not finished and not join'ed.
If the thread were busy after setting the value of the promise (i.e. doing destructors, or doing some 1-hour-long job), the std::thread's destructor invoked by } after return 0; would throw and crash the program. Hence, you need to join.

Why do we need the join function call if there is get call just 2 lines above?
Destroying a joinable std::thread object results in std::terminate() being called. This is regardless of whether or not its associated thread is done. So, the call to get() on the future is irrelevant when it comes to having to call join() on a joinable std::thread object before it is destroyed.
If you don't want to have to call join(), then you could just call detach() on the std::thread somewhere before its destruction. This way, the thread won't be joinable at the moment of destruction.

Related

If I create two std::thread, how can I identify which thread ends first

I want to create two std::thread processes. Then I want to figure out which thread ended first and end the other thread if it is still running (probably by calling its destructor?). I would like to only use the std libraries. I'm guessing I need to do something with std::atomic and/or std::future, or implement a callback?
int process1( void );
int process2( void );
std::thread first (process1() );
std::thread second (process2() );
//check which thread is done first and call join() on that thread to end it nicely?
//kill the other thread if its not done or call join() if it is done?
You can't just end a thread from outside the thread itself. You have to signal the thread in some way that it needs to stop. You can do this with a std::atomic_boolfor example.
Something like this:
// thread-safe output
#define con_sync_out(m) do{std::ostringstream o; o<<m<<'\n'; std::cout<<o.str();}while(0)
#define con_sync_err(m) do{std::ostringstream o; o<<m<<'\n'; std::cerr<<o.str();}while(0)
// random numbers
template<typename Integer>
Integer random(Integer lo, Integer hi)
{
thread_local std::mt19937 mt{std::random_device{}()};
return std::uniform_int_distribution<Integer>(lo, hi)(mt);
}
// stuff to do
void do_work(char const* id, int a, int b, std::atomic_bool& done)
{
// check if done == true (signal to stop)
while(!done && a < b)
{
++a;
con_sync_out(id << ": " << a << "/" << b);
std::this_thread::sleep_for(std::chrono::milliseconds(random<int>(500, 1000)));
}
done = true;
}
int main()
{
std::atomic_bool done = false; // signal flag
std::thread t1(do_work, "A", random<int>(0, 10), random<int>(10, 20), std::ref(done));
std::thread t2(do_work, "B", random<int>(0, 10), random<int>(10, 20), std::ref(done));
t1.join();
t2.join();
}
There's no standard/easy way to kill a thread in C++. They're not like processes.
Either detach() them both and wait in your main thread for a std::conditional_variable notification from the fastest thread if you don't mind letting the slower one finish in the background.
Or join() them both and periodically check for the std::conditional_variable in each thread to notify that the other one has finished, and then abort by returning earlier.
If neither join() nor detach() have been called before a non-empty std::thread is destroyed, then the program simply terminates.

is it safe to detach a thread and then let it go out of scope (and have it still running)?

I have the following code, which I think works ok (forgive the silly/contrived example).
void run_thread()
{
std::thread t([]{
while(true)
{
// keep getting chars... to stop peoples eye's hurting : )
char c = getchar();
}
});
t.detach(); // Detach thread
// thread goes out of scope here - but is it ok because its detached??
}
int main()
{
run_thread();
// Wait here forever
while (true) {;}
}
But after re-reading it I have a doubt about it. Thread t goes out of scope. I can't remember now if it is safe to do this after you have called detach()... I think it is, but as I say I have a nagging doubt. Can anyone confirm if this is good/bad practise?
Thread t goes out of scope. I can't remember now if it is safe to do
this after you have called detach()
You detach() because you want to disassociate the actual running thread with the thread object. So after } t goes out of scope but the actual thread will keep on running until its instruction completes.
If it weren't for detach() std::terminate would have killed the thread at }
detach basically releases the std::thread object instance which is the C++ "handle" to the actual OS thread, thereby making it impossible to join the thread later.
In most cases it's better to keep the thread instance around at some global scope so that you can join it later, for example before exiting main. That way you can ensure all threads finish before the main thread.
For example:
std::thread t; // can be "empty"
void run_thread()
{
t = std::thread([]{
while(true)
{
// keep getting chars...
char c = getchar();
}
});
}
int main()
{
run_thread();
// Wait here
std::this_thread::sleep_for(30s);
// Before exiting wait for the thread to finish
if (t.joinable())
t.join();
}
Such a usage is the point of detach.
Yes, it is ok and safe in you code. But it does not have any sense. main function will utilize CPU and a thread function will get less CPU time. You can attach to forever thread and reach similar behaviour: run_thread will never exit, thus main will never exit.
void run_thread()
{
std::thread t([]{
while(true){/* also run forever */;}
});
// Wait here forever
t.attach();
}
int main()
{
run_thread();
}

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

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;
}

std::thread thread spun off in object, when does it terminate?

If I spin off an std::thread in the constructor of Bar when does it stop running? Is it guaranteed to stop when the Bar instance gets destructed?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
...
void foo() {
while (true) {//do stuff//}
}
private:
std::thread thread;
};
EDIT: How do I correctly terminate the std::thread in the destructor?
If I spin off an std::thread in the constructor of Bar when does it
stop running?
the thread will run as long as it executing the callable you provided it, or the program terminates.
Is it guaranteed to stop when the Bar instance gets destructed?
No. In order to guarantee that, call std::thread::join in Bar destructor.
Actually, if you hadn't call thread::join or thread::detach prior to Bar::~Bar, than your application will be terminated by calling automatically to std::terminate. so you must call either join (preferable) or detach (less recommended).
you also want to call therad::join on the object destructor because the spawned thread relies on the object to be alive, if the object is destructed while your thread is working on that object - you are using destructed object and you will have undefined behavior in your code.
Short answer: Yes and no. Yes, the thread ends, but not by the usual way (killing the thread), but by the main thread exiting due to a std::terminate call.
Long answer: The thread can only be safely destructed when the underlying function (thread) has finished executing. This can be done in 2 ways
calling join(), which waits for the thread to finish (in your case, never)
calling detach(), which detaches the thread from the main thread (in this case, the thread will end when the main thread closes - when the program terminates).
If the destructor is called if all of those conditions don't apply, then std::terminate is called:
it was default-constructed
it was moved from
join() has been called
detach() has been called
The C++ threading facilities do not include a built-in mechanism for terminating a thread. Instead, you must decide for yourself: a) a mechanism to signal the thread that it should terminate, b) that you do not care about the thread being aborted mid-operation when the process terminates and the OS simply ceases to run it's threads any more.
The std::thread object is not the thread itself but an opaque object containing a descriptor/handle for the thread, so in theory it could be destroyed without affecting the thread, and there were arguments for and against automatic termination of the thread itself. Instead, as a compromise, it was made so that destroying a std::thread object while the thread remained running and attached would cause the application to terminate.
As a result, In it's destructor there is some code like this:
~thread() {
if (this->joinable())
std::terminate(...);
}
Here's an example of using a simple atomic variable and checking for it in the thread. For more complex cases you may need to consider a condition_variable or other more sophisticated signaling mechanism.
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this] () { work(); }) {}
void cancel() { running_ = false; }
~S() {
if ( running_ )
cancel();
if ( thread_.joinable() )
thread_.join();
}
private:
void work() {
while ( running_ ) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
Live demo: http://coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1

Race condition between terminating worker threads and main thread

I am having an issue with terminating worker threads from the main thread. So far each method I tried either leads to a race condition or dead lock.
The worker threads are stored in a inner class inside a class called ThreadPool, ThreadPool maintains a vector of these WorkerThreads using unique_ptr.
Here is the header for my ThreadPool:
class ThreadPool
{
public:
typedef void (*pFunc)(const wpath&, const Args&, Global::mFile_t&, std::mutex&, std::mutex&); // function to point to
private:
class WorkerThread
{
private:
ThreadPool* const _thisPool; // reference enclosing class
// pointers to arguments
wpath _pPath; // member argument that will be modifyable to running thread
Args * _pArgs;
Global::mFile_t * _pMap;
// flags for thread management
bool _terminate; // terminate thread
bool _busy; // is thread busy?
bool _isRunning;
// thread management members
std::mutex _threadMtx;
std::condition_variable _threadCond;
std::thread _thisThread;
// exception ptr
std::exception_ptr _ex;
// private copy constructor
WorkerThread(const WorkerThread&): _thisPool(nullptr) {}
public:
WorkerThread(ThreadPool&, Args&, Global::mFile_t&);
~WorkerThread();
void setPath(const wpath); // sets a new task
void terminate(); // calls terminate on thread
bool busy() const; // returns whether thread is busy doing task
bool isRunning() const; // returns whether thread is still running
void join(); // thread join wrapper
std::exception_ptr exception() const;
// actual worker thread running tasks
void thisWorkerThread();
};
// thread specific information
DWORD _numProcs; // number of processors on system
unsigned _numThreads; // number of viable threads
std::vector<std::unique_ptr<WorkerThread>> _vThreads; // stores thread pointers - workaround for no move constructor in WorkerThread
pFunc _task; // the task threads will call
// synchronization members
unsigned _barrierLimit; // limit before barrier goes down
std::mutex _barrierMtx; // mutex for barrier
std::condition_variable _barrierCond; // condition for barrier
std::mutex _coutMtx;
public:
// argument mutex
std::mutex matchesMap_mtx;
std::mutex coutMatch_mtx;
ThreadPool(pFunc f);
// wake a thread and pass it a new parameter to work on
void callThread(const wpath&);
// barrier synchronization
void synchronizeStartingThreads();
// starts and synchronizes all threads in a sleep state
void startThreads(Args&, Global::mFile_t&);
// terminate threads
void terminateThreads();
private:
};
So far the real issue I am having is that when calling terminateThreads() from main thread
causes dead lock or race condition.
When I set my _terminate flag to true, there is a chance that the main will already exit scope and destruct all mutexes before the thread has had a chance to wake up and terminate. In fact I have gotten this crash quite a few times (console window displays: mutex destroyed while busy)
If I add a thread.join() after I notify_all() the thread, there is a chance the thread will terminate before the join occurs, causing an infinite dead lock, as joining to a terminated thread suspends the program indefinitely.
If I detach - same issue as above, but causes program crash
If I instead use a while(WorkerThread.isRunning()) Sleep(0);
The program may crash because the main thread may exit before the WorkerThread reaches that last closing brace.
I am not sure what else to do to stop halt the main until all worker threads have terminated safely. Also, even with try-catch in thread and main, no exceptions are being caught. (everything I have tried leads to program crash)
What can I do to halt the main thread until worker threads have finished?
Here are the implementations of the primary functions:
Terminate Individual worker thread
void ThreadPool::WorkerThread::terminate()
{
_terminate = true;
_threadCond.notify_all();
_thisThread.join();
}
The actual ThreadLoop
void ThreadPool::WorkerThread::thisWorkerThread()
{
_thisPool->synchronizeStartingThreads();
try
{
while (!_terminate)
{
{
_thisPool->_coutMtx.lock();
std::cout << std::this_thread::get_id() << " Sleeping..." << std::endl;
_thisPool->_coutMtx.unlock();
_busy = false;
std::unique_lock<std::mutex> lock(_threadMtx);
_threadCond.wait(lock);
}
_thisPool->_coutMtx.lock();
std::cout << std::this_thread::get_id() << " Awake..." << std::endl;
_thisPool->_coutMtx.unlock();
if(_terminate)
break;
_thisPool->_task(_pPath, *_pArgs, *_pMap, _thisPool->coutMatch_mtx, _thisPool->matchesMap_mtx);
_thisPool->_coutMtx.lock();
std::cout << std::this_thread::get_id() << " Finished Task..." << std::endl;
_thisPool->_coutMtx.unlock();
}
_thisPool->_coutMtx.lock();
std::cout << std::this_thread::get_id() << " Terminating" << std::endl;
_thisPool->_coutMtx.unlock();
}
catch (const std::exception&)
{
_ex = std::current_exception();
}
_isRunning = false;
}
Terminate All Worker Threads
void ThreadPool::terminateThreads()
{
for (std::vector<std::unique_ptr<WorkerThread>>::iterator it = _vThreads.begin(); it != _vThreads.end(); ++it)
{
it->get()->terminate();
//it->get()->_thisThread.detach();
// if thread threw an exception, rethrow it in main
if (it->get()->exception() != nullptr)
std::rethrow_exception(it->get()->exception());
}
}
and lastly, the function that is calling the thread pool (the scan function is running on main)
// scans a path recursively for all files of selected extension type, calls thread to parse file
unsigned int Functions::Scan(wpath path, const Args& args, ThreadPool& pool)
{
wrecursive_directory_iterator d(path), e;
unsigned int filesFound = 0;
while ( d != e )
{
if (args.verbose())
std::wcout << L"Grepping: " << d->path().string() << std::endl;
for (Args::ext_T::const_iterator it = args.extension().cbegin(); it != args.extension().cend(); ++it)
{
if (extension(d->path()) == *it)
{
++filesFound;
pool.callThread(d->path());
}
}
++d;
}
std::cout << "Scan Function: Calling TerminateThreads() " << std::endl;
pool.terminateThreads();
std::cout << "Scan Function: Called TerminateThreads() " << std::endl;
return filesFound;
}
Ill repeat the question again: What can I do to halt the main thread until worker threads have finished?
I don't get the issue with thread termination and join.
Joining threads is all about waiting until the given thread has terminated, so it's exaclty what you want to do. If the thread has finished execution already, join will just return immediately.
So you'll just want to join each thread during the terminate call as you already do in your code.
Note: currently you immediately rethrow any exception if a thread you just terminated has an active exception_ptr. That might lead to unjoined threads. You'll have to keep that in mind when handling those exceptions
Update: after looking at your code, I see a potential bug: std::condition_variable::wait() can return when a spurious wakeup occurs. If that is the case, you will work again on the path that was worked on the last time, leading to wrong results. You should have a flag for new work that is set if new work has been added, and that _threadCond.wait(lock) line should be in a loop that checks for the flag and _terminate. Not sure if that one will fix your problem, though.
The problem was two fold:
synchronizeStartingThreads() would sometimes have 1 or 2 threads blocked, waiting for the okay to go ahead (a problem in the while (some_condition) barrierCond.wait(lock). The condition would sometimes never evaluate to true. removing the while loop fixed this blocking issue.
The second issue was the potential for a worker thread to enter the _threadMtx, and notify_all was called just before they entered the _threadCond.wait(), since notify was already called, the thread would wait forever.
ie.
{
// terminate() is called
std::unique_lock<std::mutex> lock(_threadMtx);
// _threadCond.notify_all() is called here
_busy = false;
_threadCond.wait(lock);
// thread is blocked forever
}
surprisingly, locking this mutex in terminate() did not stop this from happening.
This was solved by adding a timeout of 30ms to the _threadCond.wait()
Also, a check was added before the starting of task to make sure the same task wasn't being processed again.
The new code now looks like this:
thisWorkerThread
_threadCond.wait_for(lock, std::chrono::milliseconds(30)); // hold the lock a max of 30ms
// after the lock, and the termination check
if(_busy)
{
Global::mFile_t rMap = _thisPool->_task(_pPath, *_pArgs, _thisPool->coutMatch_mtx);
_workerMap.element.insert(rMap.element.begin(), rMap.element.end());
}