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

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.

Related

Why my program is terminated but main thread is run?

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.

Solving run-time problems with QT threads

My current problem is with two QT threads. One of them emits a signal for starting an operation in the second thread, and afterwards wait for the result. As soon as the second thread finishes, the first thread should continue with its own operation using results from the second thread.
For letting the first thread sleep I use a QMutex and a QWaitCondition. The first thread emits a signal, and afterwards sleeps at the wait condition. But the problem is now: If the second thread somehow managed to be faster than the first thread, and emits the wakeAll()-call before the first thread enters the wait-condition, I get stuck. I could implement a waiting time, but then I am unflexible again, and if the second threads needs more time than the first thread is waiting, I have a problem again.
This problem has already been addressed here: http://woboq.com/blog/qwaitcondition-solving-unavoidable-race.html, but they decided to leave this problem unsolved. So, is there a possibility to avoid this race-condition?
Addition: I don't want to convert this function into a function of the first thread, because this specific function should be accessable from several threads at once without leading to a race condition. I.e. Thread1 should call the function in Thread2, wait til it is finished, Thread3 also wants to call the function, but is not allowed to do that, it has to wait till finish, too. If the function has finished, Thread3 can access it. (Same goes for more than only two threads).
Example function:
This function should emit the signal and afterwards wait for the wake signal:
void Spectrometer_Control::moveStepper(int steps, bool dir)
{
emit stepperMoving();
qDebug() << "From Spectrometer_Control: Stepper should move in direction " + QString::number(dir) + " from position " + QString::number(MonoPos);
int newTarget = MonoPos + ((dir == true)?(steps):(-1 * steps));
qDebug() << "New target: " + QString::number(newTarget);
emit moveStepperToTarget(steps, dir);
qDebug() << "Locking WaitMutex!";
WaitMutex->lock();
qDebug() << "Waiting for signal!";
WaitForEngine->wait(WaitMutex);
WaitMutex->unlock();
qDebug() << "Finally unlocked!";
}
And this function receives the call, and should wake every waiting function up:
void Stepper_Control_Worker::moveStepper(int steps, bool dir)
{
waitMutex->lock();
qDebug() << "Motor moved from down below!";
Stepper_Control_Worker::STP[1]->setValue((dir == true)?BlackLib::high:BlackLib::low);
usleep(50000);
Stepper_Control_Worker::STP[0]->setValue(BlackLib::low);
usleep(50000);
for(int i = 0; i < steps; i++)
{
Stepper_Control_Worker::STP[0]->setValue(BlackLib::high);
usleep(50000);
Stepper_Control_Worker::STP[0]->setValue(BlackLib::low);
}
WaitCond->wakeAll();
waitMutex->unlock();
emit StepperMoved(steps, dir);
}
The second function is a sub-member (not directly, but can only accessed via) of the class "stepper_control". The stepper-controller outer controls can be used by several functions, not only the function moveStepper from Spectrometer_Control, but for making things easier I only added one external function. But after I don't want to get my stepper confused, I wanted to restrict the access as described above.
It's probably safe to let the second thread send a signal back and move the code post wait to that slot.
class Worker1: public QObject{
Q_OBJECT
//...
signals:
void startWorking();
slots:
void answer(QVariant);
};
class Worker2: public QObject{
Q_OBJECT
//...
slots:
void startWorking();
signals:
void answer(QVariant);
};
Otherwise you need to have a variable that the second thread sets while holding the QMutex to signal the first:
thread1:
emit startWorking();
{
QMutexLocker lock(&thread2->mutex);
while(!thread2->finished){//loop guards against spurious wakeups
thread2->cond->wait(&mutex);
}
}
and thread2:
{
QMutexLocker lock(&mutex);
finished=true;
cond->wakeAll();
}
That way if thread2 is faster then thread2->finished is already true by the time thread1 arrives and the mutex protects the variable between testing it and waiting on the QWaitCondition.
Maybe Qt::BlockingQueuedConnection is what you need?
a blocking queued connection is like a queued connection, but the sender thread blocks until the event is picked up by the event loop of the thread the receiver is living in, the slot is invoked, and it returns;

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.

Event synchronization between two threads in Qt

I have two threads, lets say thread "A" and thread "B".
Thread "A" post's custom QEvent to thread "B", and then it should wait till thread "B" processes this event.
What I did so far:
My event class:
class IPCMessageEvent : public QEvent
{
public:
IPCMessageEvent(QWaitCondition* pConditions) : QEvent(IPC_MESSAGE_RECEIVED)
, mpWaitCondition(pConditions)
{ };
~IPCMessageEvent()
{
mpWaitCondition->wakeOne();
};
private:
QWaitCondition* mpWaitCondition;
};
My thread "A":
QWaitCondition recvCondition;
IPCMessageEvent* pEvent = new IPCMessageEvent(&recvCondition);
QCoreApplication::postEvent(gpApp, pEvent);
QMutex mutex;
mutex.lock();
recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT);
My thread "B": Processes the received event and destroyes it. ~IPCMessageEvent destructor is called and therefore wakeOne() will be initiated for the recvCondition in thread "A".
Everything seems to work just fine, it's just one thing!
It looks like sometimes ~IPCMessageEvent is called sooner then expected...
QCoreApplication::postEvent(gpApp, pEvent);
<---- pEvent is already destroyed here ---->
QMutex mutex;
mutex.lock();
So my recvCondition.wait(&mutex, IPC_MESSAGE_WAIT_TIMEOUT); will be locked and will reach the timeout.
Are there any other ways of doing this kind of synchronization?
Or maybe someone have any suggestions how to fix/overcome this problem?
Well, you have a classical race condition. Your thread A may is interrupted directly after posting the event and thread B then processes and destroys it. Since notifications of condition variables have only an effect if somebody is already waiting, you miss the notification and thus your block infinitely.
So you need to lock the mutex before posting the event. However, this requires that your thread B also needs to lock this mutex when processing the event. Otherwise, you cannot prevent the race condition as thread B has no reason to wait for anything (or to know that it should "wait" until thread A is ready waiting on the condition variable).
Alternative:
If you use a signal/slot connection between the two threads (or the objects living in the two threads), you can use a Qt::BlockingQueuedConnection. This ensures that thread A blocks after emitting the signal until the event loop in thread B processed it.
Thanks Johannes,
I would really need to try and use your suggested alternative with signals/slots.
What I did for now is:
I've created a QMutex and boolean flag that are used between thread "A" and thread "B".
bool mIsProcessingMessage;
QMutex mIsProcessingMessageLock;
In thread "A" I'm posting my event like this:
IPCMessageEvent* pEvent = new IPCMessageEvent();
{ // Inform everyone that we will be processing our message.
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = true;
};
QCoreApplication::postEvent(gpApp, pEvent, Qt::HighEventPriority);
forever // Loop until event will get processed.
{
QMutexLocker locker(&mIsProcessingMessageLock);
if (mIsProcessingMessage == false)
break;
::Sleep(2); // Don't load up the CPU.
};
In thread "B" when my event is processed I just set my "mIsProcessingMessage" flag to true like this:
{
QMutexLocker locker(&mIsProcessingMessageLock);
mIsProcessingMessage = false;
};
Maybe it's not the best solution, but it works for now ;)

Wxwidgets callback

i would like to add a callback function to a threaded function without freezing the main application.
Ex: when I click on a button, it start a threaded function. I wanna inform the user when the work is finish.
Thx
cs functions;
pthread_t thread;
pthread_create(&thread, NULL, maFonction, (void*)&functions);
//pthread_join(thread, NULL);
The pthread_join block the main application when waiting for the thread to finish. So how would I do it. Thx a lot
Make the thread in a detached state by calling pthread_detach() in the spawned thread, or when creating the thread in the main thread, set the pthread attributes for that thread to a detached state. Now that the thread is detached, you won't need to call pthread_join() in the main thread. Next, in the spawned thread itself, before exiting the thread, push an event onto event queue of the WxWidgets object that spawned the thread in order to "announce" that the spawned thread has completed. Finally, add an event handler for your thread-finishing event to your WxWidget object to handle the even the spawned thread will place on it's event queue.
For instance, you could create an event like THREAD_FINISHED_EVENT that you thread will push onto the event-queue of the object that will spawn the threads. You code would look like the following:
wxCommandEvent event(THREAD_FINISHED_EVENT, GetId());
//"this" points to the parent WxWidgets object spawning the threads
//and allows you to access the "this" pointer in the handler
event.SetEventObject(this);
//Send the event
this->AddPendingEvent(event);
The event itself will be processed in the main event thread of the WxWidget that installs the handler for the event. You'll just need to provide a handler for the WxWidget object, and define the event itself. This can be done using the macro DEFINE_EVENT_TYPE, and then adding the following line to the constructor of the WxWidget object that will be spawning the threads themselves:
//myWxWidget::thread_handler is the handler for your thread ending events
Connect(widgetID, THREAD_FINISHED_EVENT, wxCommandEventHandler(myWxWidget::thread_handler))
Summing this all up, here's what some theoretical WxWidgets object class would look like:
//myWindowThreadClass.hpp
#include <wx/wx.h>
#include <wx/event.h>
extern expdecl const wxEventType THREAD_FINISHED_EVENT;
class myWindowThreadClass: public wxWindow
{
public:
myWindowThreadClass(wxWindow* parent, int id);
//handler for the thread-ending event
void thread_handler(wxCommandEvent& event);
//pushes a thread event on the wxWidgets event-queue
//for myWindowThreadClass
void send_thread_event();
};
//myWindowThreadClass.cpp
#include <myWindowthreadClass.h>
#include <pthread.h>
const wxEventType THREAD_FINISHED_EVENT = wxNewEventType();
void* thread_func(void* data)
{
myWindowThreadClass* window_ptr = static_cast<myWindowThreadClass*>(data);
//detach thread
pthread_detatch(pthread_self());
//... rest of thread function
window_ptr->send_thread_event();
return (void*)0;
}
myWindowThreadClass::myWindowThreadClass(wxWindow* parent, int id):
wxWindow(parent, id)
{
//enable the event handler
Connect(id, THREAD_FINISHED_EVENT, wxCommandEventHandler(myWindowThreadClass::thread_handler));
//create your threads
pthread_t tid;
for (int i=0; i < NUM_THREADS; i++)
{
pthread_create(&tid, NULL, thread_func, this);
}
//...do anything else needed to initialize object
}
void myWindowThreadClass::thread_handler(wxCommandEvent& event)
{
//handle the event
}
void myWindowThreadClass::send_thread_event()
{
wxCommandEvent event(THREAD_FINISHED_EVENT, GetId());
event.SetEventObject(this);
//Send the event ... import to use this function, as it will cause
//the event to be processed in main-thread, not spawned child threads
this->AddPendingEvent(event);
}
Set a variable, eg. xxx_is_done, to false before starting the thread. And when the thread is done, the last thing it does is set xxx_is_done to true. Then just check the variable in the main event loop and call pthread_join on the thread when the variable is true and also set the variable back to false so you don't call pthread_join on the thread again.