How does thread::detach() work in C++11? - c++

I wrote the following code and am unable to understand why doesn't it prints out all the no's(i.e. 0 to -99) in threadFunc() as it does with main() thread.
#include<iostream>
#include<thread>
#include<string>
#include<mutex>
#include<chrono>
using namespace std;
mutex mu;
void threadFunc(){
for(int i=0;i>-100;i--){
std::this_thread::sleep_for(std::chrono::milliseconds(30)); /*delay for 30ms*/
mu.lock();
cout<<"Thread: "<<i<<endl;
mu.unlock();
}
}
main(){
thread t1(threadFunc);
for(int i=0;i<100;i++){
mu.lock();
cout<<"Main: "<<i<<endl;
mu.unlock();
}
cout<<"End of Main"<<endl;
t1.detach();
}
The output of the program is:
Main: 0
Main: 1
.
.
.
Main: 99
End of Main.
Thread: -1

Process terminates when main() exits, and all threads are killed. You observe this behavior in your program.
Detach basically says that from now on, you can't join this thread. But if you can't join it, you can't make your main() to wait until it completes (unless you use other synchronization primitives) - and thus it is happily exiting.
This is why I strongly discourage everybody from using detached threads, they are very hard to do properly.

The detach function prevents an exception from being thrown when the thread object goes out of scope. Usually, you would want to call join but if you don't want to block the execution you need to call detach. However, you probably need to use another synchronization mechanism to make sure everything is fine if the thread is still running when main is ready to exit. See the following contrived example.
Example Code
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
std::mutex mu;
std::condition_variable cv;
bool finished = false;
void threadFunc()
{
for (int i = 0; i < 5; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
std::unique_lock<std::mutex> lock(mu);
std:: cout << "Thread: " << (0 - i) << "\n";
}
std::unique_lock<std::mutex> lock(mu);
finished = true;
cv.notify_one();
}
int main()
{
{
std::thread t1(threadFunc);
t1.detach(); // Call `detach` to prevent blocking this thread
} // Need to call `join` or `detach` before `thread` goes out of scope
for (int i = 0; i < 5; ++i)
{
std::unique_lock<std::mutex> lock(mu);
std::cout << "Main: " << i << "\n";
}
std::cout << "End of Main\n";
std::unique_lock<std::mutex> lock(mu);
cv.wait(lock, [&finished]() { return finished; });
return 0;
}
Example Output
Main: 0
Main: 1
Main: 2
Main: 3
Main: 4
End of Main
Thread: 0
Thread: -1
Thread: -2
Thread: -3
Thread: -4
Live Example
Again, the above is a contrived example and in your case you could more easily use join instead of detach before allowing main to return.

Related

How to correctly wait for condition variable timeout

I'm working on simple cancellation mechanism. But I have found problem with waiting for timeout on condition variable.
Lets consider the sample program from:
https://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
It looks like this sample is broken. If someone would provide the data very fast then the program would go into infinite loop. To visualize it I did little modification to the sample program:
#include <iostream> // std::cout
#include <thread> // std::thread
#include <chrono> // std::chrono::seconds
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status
using namespace std::chrono_literals;
std::condition_variable cv;
int value = -1;
void compute() {
value = 0;;
cv.notify_one();
}
int main()
{
std::thread th(compute);
std::this_thread::sleep_for(1s);
std::mutex mtx;
std::unique_lock<std::mutex> lck(mtx);
while (cv.wait_for(lck, std::chrono::seconds(1)) == std::cv_status::timeout) {
std::cout << '.' << std::endl;
}
std::cout << "You entered: " << value << '\n';
th.join();
return 0;
}
As I can't type as fast I just set the value to 0 and execute notify_one.
On the main thread I simulate simple delay. sleep_for(1s).
Finally the program does not see the notify_one and loops infinitely.
The output is: .....
My question is how to implement it correctly ?
I would like to know also if the waiting was stopped by timeout.
If the notify happens before the wait then it indeed gets "lost".
Most usage of CVs also require a flag of some sort which should be checked in the predicate. You already have this flag - value. Just use this as a predicate:
EDIT: Removed wrong code.
Note that as a separate matter you should protect the writing to value with your mutex or you're likely to hit UB. Which means you need to make your mutex global along with the CV/Flag.
Better way:
auto endTime = std::chrono::now() + std::chrono::seconds(1);
while(flag != 0)
{
auto res = cv.wait_until(lck, endTime);
if (res == std::cv_status::timeout)
{
// Add Timeout logic here
break;
}
}

(Congruence) Why does the std:: before the first thread make it print second?

#include <iostream>
#include <thread>
void foo(){
std::cout << "Thread 1 \n";
}
void bar(){
std::cout<< "Thread 2 \n";
}
using namespace std;
int main()
{
std::thread t1(foo);
thread t2(bar);
t1.join();
t2.join();
return 0;
}
The above code gives me an output of Thread 1 \n Thread 2. However, when I change std::thread t1(foo); to thread t1(foo);, my output is Thread 2 \n Thread 1. Why is this?
The compiler I'm using for this is: https://www.onlinegdb.com/online_c++_compiler
Using std:: has absolutely no impact here. You simply do not have any control over in which order the threads will be run so you can get any order.

C++14 thread/condition variable misunderstanding

I'm trying to run a thread with a function from a class member and use conditional variable to wait until the main thread signals and add the times the thread got signaled. Here is the code:
// Example program
#include <iostream>
#include <string>
#include <atomic>
#include <thread>
#include <unistd.h>
#include <mutex>
#include <condition_variable>
std::mutex m_mutex;
std::condition_variable m_condVar;
char stop =0;
class dummclass
{
std::thread dummclass_thread;
int alarms;
public:
dummclass() :
alarms(0),
dummclass_thread(std::thread(&dummclass::dummclassThreadProc, this))
{
}
~dummclass()
{
std::cout<<"Alarms: "<<alarms<<"\n";
//signal thread before joining
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
stop=1;
}
m_condVar.notify_one();
dummclass_thread.join();
}
private:
void dummclassThreadProc()
{
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout<<"thread waiting\n";
m_condVar.wait(mlock);
std::cout<<"thread done waiting\n";
}
sleep(1);
std::unique_lock<std::mutex> mlock(m_mutex);
while (!stop)//!stop_dummclass.load())
{
std::cout<<"got mutex\n";
m_condVar.wait(mlock);
std::cout<<"wait done\n";
{
std::cout<<"got one\n";
alarms++;
}
}
std::cout<<"end loop\n";
}
};
int main()
{
dummclass *x = new dummclass;
sleep(3);
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
}
m_condVar.notify_one();
std::cout<<"done waiting\n";
sleep(3);
for(int i=0;i<13;i++)
{
{
std::cout<<"signal "<<i<<"\n";
std::lock_guard<std::mutex> lock_guard(m_mutex);
}
m_condVar.notify_one();
}
delete x;
}
The weird part is that the initial waiting and signaling that are outside of the loops actually work ok. I don't understand what mistake I do so that the while loop inside the class thread doesn't catch any signal from the main thread but it catches a signal from the destructor of the dummyclass when I delete it. This is the output:
thread waiting
done waiting
thread done waiting
got mutex
signal 0 signal 1 signal 2 signal 3 signal 4 signal 5 signal 6 signal 7 signal
8 signal 9 signal 10 signal 11 signal 12
Alarms: 0
wait done
got one end loop
EDIT: It seems that adding a 1 second sleep in the main() for loop solves the problem. Is it possible that the for loop gets the mutex before wait() manages to wake and lock the mutex ?
for(int i=0;i<13;i++)
{
{std::cout<<"signal "<<i<<"\n";
std::lock_guard<std::mutex> lock_guard(m_mutex);}
m_condVar.notify_one();
sleep(1);
}
Can someone please show me what is wrong ?
Thanks.
The object doing the waiting gets deleted before it processes the signal. Since the delete happens on a known to be running thread it has a fair chance to get executed first. In particular it is also likely to reacquire the lock again: Since the notify_one() is done while the mutex is locked the wait()ing thread cannot acquire it and will go back to sleep, waiting for the mutex to be released. That gives the signalling thread an opportunity to reacquire the lock. The only forced synchronizqtion causing the signalling thread to wait is the join() and it does give the waiting thread a chance to execute.
Note that signals of condition variables are not something delivered to the waiting thread. They are essentially wake-up calls. The waiting thread will wake up eventually once a signal is delivered. However, many signals can be delivered before it actually does so.
I don't understand what mistake I do so that the while loop inside the
class thread doesn't catch any signal from the main thread
Even though multiple notifications are sent the thread may only receive a single notification.
The notify_one() call does
not mean that the current thread will stop and wait for another thread.
It just means that the other thread must wake up at some point because something may have happened that it would be interested in.
Also note that std::condition_variable::wait could experience a spurious wakeup, so it might not even have anything to do or have received a 'real' signal.
The solution is to provide a predicate as a parameter to the wait() call. The predicate can then check if there is a signal (via a variable provided for this purpose and only changed under lock) and may also check if the program has been stopped.
In the updated program below I've added a predicate to the wait and made some minor changes. The program only notifies under lock, but you might choose not to.
// Example program - modified
#include <iostream>
#include <string>
#include <atomic>
#include <thread>
//#include <unistd.h>
#include <mutex>
#include <condition_variable>
#include <chrono>
std::mutex m_mutex;
std::condition_variable m_condVar;
bool signal_waiting{false};
bool stop{false};
class dummclass
{
int alarms{};
std::thread dummclass_thread{[this](){dummclassThreadProc(); }};
public:
~dummclass()
{
std::cout << "Alarms: " << alarms << "\n";
//signal thread before joining
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
stop = 1;
m_condVar.notify_one();
}
dummclass_thread.join();
}
private:
void dummclassThreadProc()
{
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout << "thread waiting\n";
m_condVar.wait(mlock);
std::cout << "thread done waiting\n";
}
std::this_thread::sleep_for(std::chrono::seconds{1});
while(!stop)//!stop_dummclass.load())
{
std::unique_lock<std::mutex> mlock(m_mutex);
std::cout << "got mutex\n";
//m_condVar.wait(mlock);
m_condVar.wait(mlock, [](){return signal_waiting || stop; });
if(stop)
break;
std::cout << "wait done\n";
std::cout << "got one\n";
alarms++;
signal_waiting = false;
m_condVar.notify_one();
}
std::cout << "end loop\n";
}
};
int main()
{
dummclass *x = new dummclass;
//sleep(3);
std::this_thread::sleep_for(std::chrono::seconds{1});
{
std::lock_guard<std::mutex> lock_guard(m_mutex);
m_condVar.notify_one();
}
std::cout << "done waiting\n";
//sleep(3);
std::this_thread::sleep_for(std::chrono::seconds{1});
for(int i = 0; i<13; i++)
{
{
std::cout << "signal " << i << "\n";
std::unique_lock<std::mutex> lock(m_mutex);
m_condVar.wait(lock, [](){return !signal_waiting ; });
signal_waiting = true;
m_condVar.notify_one();
}
}
delete x;
}

Multi-threaded event checker does not print anything

Code:
#include <iostream>
#include <future>
#include <queue>
#include <boost/thread/thread.hpp>
boost::mutex mtx;
std::queue<std::string>ev;
void t_1(){
while(true){
mtx.lock();
if(ev.size() > 0){
std::cout << ev.front();
ev.pop();
}
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
}
}
void t_2(){
int x = 0;
while(true){
x++;
mtx.lock();
ev.push("new event");
mtx.unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}
}
void t_3(){
while(true){
std::cout << 3;
}
}
int main(int argc, const char * argv[]) {
// insert code here...
boost::thread t1(t_1);
boost::thread t2(t_2);
//boost::thread t3(t_3);
t1.join();
t2.join();
while(true){
std::cout << "anyone there";
}
//t3.join();
return 0;
}
I was messing around with the boost library, and wanted to make an event checker using threads and mutexes. For some reason there is no output, even on the main thread when it should print "anyone there." I am using Mac OSX and Xcode. THe program compiles and runs just fine.
As already mentioned by #krzaq your main loop does not print anything because join waits for the termination of the thread, which will never happen due to the endless loops in t_1 and t_2.
As for your t_1 output: You have no newline in your output. Typically the output buffer is flushed only on a newline, which means that you will not see the output flushed to your terminal until you either print a newline or the buffer is filled up.
Try this:
std::cout << ev.front() << "\n";
Your threads never finish, and you join() them (that is, wait for them to finish) before the printing loop in the main thread.
t1.join(); // the main thread never gets past this point

Threads exiting prematurely

I have the following piece of code, meant to create two threads and execute them indefinitely. But when run, it exits after some iterations.
#include <iostream>
#include "error.h"
#include <cstdlib>
#include <pthread.h>
#include <string>
#include <time.h>
#include <sys/wait.h>
using namespace std;
#define NUM_THREADS 2
#define TIME_OUT 3
void *GoBackN(void* arg) {
while(true) cout<<"Thread executing"<<endl;
}
int main()
{
pthread_t t[NUM_THREADS];
pthread_create((&t[0]),NULL,&GoBackN,NULL);
pthread_create((&t[1]),NULL,&GoBackN,NULL);
wait(NULL);
return 0;
}
Output -
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Thread executing
Process returned 0;
I'm compiling on g++, and running a linux machine.
You have three threads and you allow the main thread to exit.
#include <iostream>
#include "error.h"
#include <cstdlib>
#include <pthread.h>
#include <string>
#include <time.h>
#include <sys/wait.h>
using namespace std;
#define NUM_THREADS 2
#define TIME_OUT 3
void* GoBackN(void* arg) {
while(true) cout<<"Thread executing"<<endl;
}
int main() // main thread starts here
{
pthread_t t[NUM_THREADS];
pthread_create((&t[0]),NULL,&GoBackN,NULL); // second thread starts here
pthread_create((&t[1]),NULL,&GoBackN,NULL); // third thread starts here
wait(NULL); // doesn't wait for very long (zero time)
// ...
// main thread keeps running here...
// ...
return 0; // whoops main thread ends closing program
}
You could put an infinite loop (or an infinite wait) in the main thread to stop it exiting the program.
int main()
{
pthread_t t[NUM_THREADS];
pthread_create((&t[0]),NULL,&GoBackN,NULL);
pthread_create((&t[1]),NULL,&GoBackN,NULL);
wait(NULL); // doesn't wait for very long (zero time)
// ...
// loop in the main thread too
while(true) cout<<"Main thread executing"<<endl;
// ...
return 0; // now we don't get here
}
Or more typically join the threads waiting for them to exit:
int main() // main thread starts here
{
pthread_t t[NUM_THREADS];
pthread_create((&t[0]),NULL,&GoBackN,NULL); // second thread starts here
pthread_create((&t[1]),NULL,&GoBackN,NULL); // third thread starts here
wait(NULL); // doesn't wait for very long (zero time)
// ...
// join threads here
pthread_join(t[0], nullptr);
pthread_join(t[1], nullptr);
// ...
return 0; // we get here when other threads end
}
Now the main thread is suspended and does not consume any CPU time while the other threads are running.
If you are using a modern compiler with C++11 support you can use the Standard Library threads something like this:
#include <thread>
#include <chrono>
#include <vector>
#include <sstream>
#include <iostream>
const int number_of_threads = 5;
// nasty little MACRO to provide synchronized output (crude but works)
#define SYNC_OUT(m) do{std::ostringstream o; o << m << '\n'; std::cout << o.str();}while(0)
void GoBackN(int id) {
while(true)
{
SYNC_OUT("Thread: " << id << " executing");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
int main() // main thread starts here
{
std::vector<std::thread> threads;
for(int i = 0; i < number_of_threads; ++i)
threads.emplace_back(GoBackN, i); // start new thread
// ...
// join threads here
for(auto&& thread: threads)
thread.join();
}
I'd recommend using <thread> or <future>s std::async. After you create threads, you should either .join() them later or .detach() them, whereas .join() halts the main programs execution and .detach() does not.
#include <thread>
#include <iostream>
void foo()
{
std::cout << "print from thread" << std::endl;
}
int main()
{
std::cout << "before the thread starts" << std::endl;
std::thread t(foo);
t.join();
std::cout << "after thread finishes" << std::endl;
}
For more information you really should check out this for example.