Why my program is terminated but main thread is run? - c++

I run thread in Qmainwindow using thread library not qthread
I not use thread.join but main thread is run but program is terminated
why program is temianted?
void MainWindow::onSendMsg()
{
// std::thread trdSend([this](){
socket = new QTcpSocket(this);
socket->connectToHost(clientIP,clientPort.toUInt());
//socket->close();
QLabel *lblMsg = new QLabel;
QByteArray data;
qDebug()<<"New Message";
if(filePath.isNull() || filePath.isEmpty())
{
qDebug()<<"Message is Text";
QString msg=leMsg->text();
qDebug()<<"Message : "<< msg;
data =msg.toUtf8();
data.insert(0,'0');
qDebug()<<"Add Flag To Message";
//lblMsg->setText(msg);
qDebug()<<"Message Is Ready";
socket->write(data);
std::thread trdSend((Send()),&data);
//trdSend.join();
emit addWidget(true,true,data);
}

Literally from std::thread::~thread:
~thread(); (since C++11)
Destroys the thread object.
If *this has an associated thread (joinable() == true), std::terminate() is called.
Notes
A thread object does not have an associated thread (and is safe to destroy) after
it was default-constructed
it was moved from
join() has been called
detach() has been called
The instance std::thread trdSend; is created as local variable.
After the emit addWidget(true,true,data); the scope is left and the trdSend is destroyed while none of the four conditions is met.

The std::thread trdSend leaves scope so its destructor is called without thread being joined. So it is still joinable. Therefore the program is required to terminate.
It terminates because what your code does is programming error. It is made that way because we want either:
work thread to send our main program some kind of signal about if it succeeded or failed and so our program knows that the work is done and thread can be joined.
our main thread to wait in join until work is done.
detach the thread as we don't really care how it went. But that is odd so we have to be explicit there.

Related

Relation between running Thread and the thread object

While learning basic thread management, I found difficulty in understanding these lines (in bold) from a book.
Once you’ve started your thread, you need to explicitly decide whether
to wait for it to finish (by joining with it—see section 2.1.2) or
leave it to run on its own (by detaching it—see section 2.1.3). If you
don’t decide before the std::thread object is destroyed, then your
program is terminated (the std::thread destructor calls
std::terminate()). It’s therefore imperative that you ensure that the
thread is correctly joined or detached, even in the presence of
exceptions. See section 2.1.3 for a technique to handle this scenario.
Note that you only have to make this decision before the std::thread
object is destroyed—the thread itself may well have finished long
before you join with it or detach it, and if you detach it, then the
thread may continue running long after the std::thread object is
destroyed.
When does a thread run even after the thread object is destroyed? Anyone have sample code or any reference?
What this means is that the lifetime of the thread is not associated with the lifetime of the thread object.
So the following code:
#include <thread>
#include <iostream>
int main() {
{ //scope the thread object
std::thread thr = std::thread([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Thread stuff\r\n";
});
thr.detach();
} //thr is destroyed here
std::cout << "thr destroyed, start sleep\r\n";
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "sleep over\r\n";
}
Will output:
thr destroyed, start sleep
Thread stuff
sleep over

Why does this simple threaded C++ program crash upon exit unless I call thread.join()?

The program below will end up failing with a message regarding abort() being called.
I'm starting a thread that simple prints to cout. If I use std::this_thread::sleep_for(), I get the error. If I remove this, I get the error. If I call join() on the thread, everything works fine.
Shouldn't the thread have terminated long before the 1000 ms delay was up? Why is this causing an error? I can't believe calling join() is a requirement for a thread.
#include <thread>
#include <iostream>
class ThreadTest
{
public:
ThreadTest() : _t{ &ThreadTest::Run, this } {}
void Wait() { _t.join(); }
private:
void Run(){
std::cout << "In thread" << std::endl;
}
std::thread _t;
};
int main(int argc, char *argv[])
{
ThreadTest tt;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// tt.Wait();
return 0;
}
According to cppreference on thread class destructor :
~thread(): Destroys the thread object. If *this still has an associated running thread (i.e. joinable() == true), std::terminate() is called.
And joinable() :
[...] A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.
So you have to call join() explicitely before your thread variable is automatically destroyed or use the detach() member function.
Check cppreference's std::thread page.
A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.
[the destructor] Destroys the thread object. If *this still has an associated running thread (i.e. joinable() == true), std::terminate() is called.
To get the behavior you want, you'd need to call _t.detach() before exiting from main:
[detach()] Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.
After calling detach *this no longer owns any thread.

Unable to connect between QThread with finished() signal for multiple Qthread

I have a 3 QThreads invoking by one another (all inherited from QThread. I know some might suggest to use moveToThread, but just ignore this fact for now). The simplified code looks like following:
Thread1 class:
void
Thread1::run
{
// some execution
Thread2 t2 = new Thread2();
connect(t2,SIGNAL(finished),this,SLOT(onFinished));
t2->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread1::onFinished(){ stop = true; }
Thread2 class:
void
Thread2::run
{
// some execution
Thread3 t3 = new Thread3();
connect(t3,SIGNAL(finished),this,SLOT(onFinished));
t3->start();
while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread2::onFinished(){ stop = true; }
Thread3 class:
void
Thread3::run
{
// some execution
QMutexLocker ml(&mMutex);
}
When I have only two threads, it works perfectly fine (e.g. just thread2 and thread3). The onFinished() method seems not connecting with finished() signal properly anymore, after I moved to a three-threads scenario. The onFinished() in thread2 has ever been called. And I am pretty sure the execution of the thread3 has completed.
Can anybody tell me where I could have done wrong?
First of all you should note that the default connection type is Qt::AutoConnection. This means if signal is emitted from a different thread than the receiving object's thread, Qt::QueuedConnection is used. In this case: The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. So you need an event loop.
It works with 2 threads because you probably have an event loop running in your main thread. In your case where you use only thread2 and thread3 objects, thread2 object will actually live in the main thread, while thread3 object will live in the thread managed by the thread2 object. So slots in thread2 object should work.
But in the case of 3 threads, thread1 object would live in the main thread, thread2 object would live in the thread managed by thread1 object, and because there is no running event loop there, the slot in thread2 object will never be executed.
You can call QThread::exec() in your QThread::run() function, but note that the slots will be executed in the thread where your QThread object lives in, not the thread it manages. Because of this you shouldn't use slots in QThread subclasses. You should create a QObject subclass and move it to a thread.
Another option is to use Qt::DirectConnection for the connection type, when you connect your signals to slots.

Telling an std::thread to kill/stop itself when a condition is met

Say I have a worker thread tWorker, which is initialized when Boss is constructed and tells it to do work(), until bRetired is true. An std::mutex, mtx, locks some data (vFiles) so that tWorker owns it when he's working on it.
How do I make tWorker "commit suicide" once bRetired becomes true? How would the mutex be destroyed when the thread stops execution?
I've read that std::thread objects cannot be interrupted in any way. Does letting the thread do nothing (or calling std::this_thread::yield()) provide the same effect as killing the thread?
class Boss {
private:
std::thread tWorker;
std::mutex mtx;
bool bRetired;
std::vector< std::string > vFiles;
void work() {
while ( bRetired == false ) {
// Do your job!
mtx.lock();
// ... Do something about vFiles ...
mtx.unlock();
}
// tWorker has retired, commit suicide
// ** How? **
// Does this suffice if I want to "kill" the thread?
std::this_thread::yield();
}
public:
Boss() {
bRetired = false;
tWorker = std::thread( &Boss::work, this );
// Have worker do its job independently
// **Bonus Question** : Should this be tWorker.join() or tWorker.detach()?
tWorker.detach();
}
retire() {
bRetired = true;
}
}
Notes
The worker thread cannot be started again once it is retired.
The worker thread works on the background without interrupting the main thread's execution.
How do I make tWorker "commit suicide" once bRetired becomes true?
You let the control flow exit the thread function. That std::this_thread::yield() call in unnecessary.
How would the mutex be destroyed when the thread stops execution?
That mutex is a member of Boss class. It gets destroyed in the destructor of Boss when the object is getting destroyed.
I've read that std::thread objects cannot be interrupted in any way.
C++ API does not provide means to terminate an arbitrary thread. There has to be a way to tell a thread to terminate and then wait till it does, as you intend to do.
Does letting the thread do nothing (or calling std::this_thread::yield()) provide the same effect as killing the thread?
No.
There is a race condition on bRetired variable though. It either needs to be std::atomic<bool> or it should only be read and modified only when that mutex is locked.
The call to std::thread::yield() is unrequired and does not kill the calling thread:
Provides a hint to the implementation to reschedule the execution of threads, allowing other threads to run.
Just exit the function to exit the thread.
Note that the use of bRetired is incorrect as two threads can be accessing the same memory location and one of those threads is modifying it: this is undefined behaviour. Also, the change made in the function retire(), a different thread, will not be seen by the thread executing run(): use atomic<bool> for atomicity and visibility.
If join() was used within the constructor the constructor would not return until the thread exited, which would never happen as it would be impossible to call retire() because the object would not be available (as the constructor would not have returned). If it is required to synchronize with the exiting of the thread then do not detach() but join() in the retire() function:
void retire() {
bRetired = true;
tWorker.join();
}
Use RAII for acquiring mutexes (std::lock_guard for example) to ensure it always released. The mutex will be destroyed when it goes out of scope, in this case when its containing class is destructed.

std::thread::detach causes crash after original caller is destroyed

struct Test {
bool active{true};
void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}
Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}
~Test() {
// somehow stop the detached thread?
}
};
When an instance of Test is initialized, it spawns and detaches an std::thread which runs in background. When the same instance is destroyed, the previously mentioned thread tries to access the active member, which was destroyed along with the instance, causing a crash (and an AddressSanitizer backtrace).
Is there a way to stop the detached thread on ~Test()?
The design is bad. How should a thread running in background until the caller is destroyed be spawned/handled correctly?
Make the thread a member of the class, and instead of detaching it in the constructor, join it in the destructor. To stop the thread from looping, you can have a boolean inside the class that signals whether the thread should continue running or not (std::atomic<bool> update).
The thread could be executing this: [this] { while (update) threadUpdate(); }.
In the destructor of your class, do update = false, and call thread.join()
You can't stop detached threads. That's the point of .detach() - you don't have any way to refer to the detached thread anymore, at least as far as the C++ standard specifies. If you want to keep a handle to the thread, store the std::thread and call .join() in the destructor.