QThread::currentThread () vs QObject::thread() - c++

I am looking for an answer if there is any difference between these two functions, aside from the constness of the first one:
QThread * QObject::thread() const
QThread * QThread::currentThread()

They are quite different.
QThread * QObject::thread() const returns the thread in which a particular QObject lives.
QThread * QThread::currentThread() Returns a pointer to a QThread which manages the currently executing thread.
class MyClass : public QObject
{
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyClass * obj = new MyClass();
QThread thread2;
obj->moveToThread(&thread2);
thread2.start();
qDebug() << "The current thread is " << QThread::currentThread();
qDebug() << "The thread2 address is " << &thread2;
qDebug() << "The object is in thread " << obj->thread();
return app.exec();
}
Sample output:
The current thread is QThread(0x1436b20)
The thread2 address is QThread(0x7fff29753a30)
The object is in thread QThread(0x7fff29753a30)

They do two different things.
QThread::currentThread() is a static function that returns a pointer to the thread which it is called from, ie. current thread.
QObject::thread() returns a pointer to the thread in which this object lives in.

They are not the same although they might return the same result.
1st one returns the thread that the QObject lives in.
2nd one returns the currently executing thread.

Related

What happens with Qt::BlockingQueuedConnection emission if target object dies?

When I send a method call using invokeMethod, what happens when the sending code waits on the call, but the target object dies subsequently? Will this end in an infinite wait? Or will Qt wake up the caller and return false (which would be an undocumented behavior, and a best guess by myself)?
The following example deletes the worker object while invokeMethod is waiting for a BlockingQueuedConnection:
#include <QtCore>
//a thread that can be destroyed at any time
//see http://stackoverflow.com/a/25230470
class SafeThread : public QThread{
using QThread::run;
public:
explicit SafeThread(QObject* parent= nullptr):QThread(parent){}
~SafeThread(){ quit(); wait(); }
};
//The function queues a functor to get executed in a specified worker's thread
template <typename Func>
void PostToThread(QThread* thread, Func&& f) {
//see http://stackoverflow.com/a/21653558
QObject temporaryObject;
QObject::connect(&temporaryObject, &QObject::destroyed,
thread->eventDispatcher(), std::forward<Func>(f),
Qt::QueuedConnection);
}
//a typical QObject worker that can "printName"
class Worker : public QObject {
Q_OBJECT
public:
using QObject::QObject;
~Worker() {
qInfo() << "destroying " << objectName()
<< " in " << QThread::currentThread()->objectName();
}
Q_SLOT void printName() {
qInfo() << "my name is " << objectName()
<< " in " << QThread::currentThread()->objectName();
}
};
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
//create worker
Worker *worker = new Worker;
worker->setObjectName("worker");
//start worker thread and move worker to it
SafeThread t;
worker->moveToThread(&t);
t.start();
//set thread names (for better output)
QThread::currentThread()->setObjectName("main_thread");
t.setObjectName("worker_thread");
//normal QMetaObject::invokeMethod usage
if(QMetaObject::invokeMethod(worker, "printName",
Qt::BlockingQueuedConnection)) {
qInfo() << "printName called successfully before deletion";
}
//the lambda function will be executed in the worker thread
PostToThread(&t, [worker]{
qInfo() << "blocking " << QThread::currentThread()->objectName();
QThread::sleep(2); //block worker thread for 2 seconds
delete worker; //delete worker
});
//at this point the worker thread is about to destroy the worker object (but
//hasn't done so yet)
if(QMetaObject::invokeMethod(worker, "printName",
Qt::BlockingQueuedConnection)) {
qInfo() << "printName called successfully after deletion!";
}
QTimer::singleShot(100, &a, &QCoreApplication::quit);
return a.exec();
}
#include "main.moc"
Output (tested on Qt 5.9.1, Qt 5.7 - windows, debian):
my name is "worker" in "worker_thread"
printName called successfully before deletion
blocking "worker_thread"
destroying "worker" in "worker_thread"
printName called successfully after deletion!
So a short answer is: invokeMethod returns true but nothing gets called. However, please note that you have to guarantee that the worker object is still valid at the beginning of (see last point for more details) the invokeMethod call the main thread (otherwise, it is UB).
Here is a list of conclusions that I got into by digging through Qt's code:
ivokeMethod returns false only when there is a problem in the parameters passed to it (e.g. slot signature does not match parameters count/type, return type mismatch, unknown connection type, ...). See here.
When using Qt::BlockingQueuedConnection, invokeMethod blocks the calling thread by acquiring a QSemaphore. The QSemaphore is stored into the QMetaCallEvent that is posted to the receiver object.
This QSemaphore is released when the QMetaCallEvent is destroyed.
QObject's destructor is responsible for calling QCoreApplication::removePostedEvents() for the object being destructed. This means that all the events in the event queue that are targeted to an object are destroyed upon this object's destruction. See here.
You need to make sure that the worker object stays alive while the calling thread executes invokeMethod until the mentioned semaphore is acquired, because invokeMethod might try to access the worker object at any point. I think that this requirement can make things complicated in practice, as one might end up having to guarantee the lifetime of the object throughout the whole invokeMethod call (and hence avoiding this whole question).

C++ stack memory management questions

I'm trying to understand C++ memory management. As far as I know, objects on stack are guaranted to live (if stack is now overflown) only in current block of code. If I call a function from this block and pass a link of a stack object to this function it must work because calling block is still alive.
What happens with stack objects if I start a new thread from current block of code? As far as I understand this block is considered as finished.
The problem is that stack variables live some time after block finishes so I can't understand if they are guaranted to live or not.
Here I have some code. It compiles and works well but I suppose that it is not guaranted to work.
main.h:
#include <QObject>
#include <QThread>
#ifndef MAIN_H
#define MAIN_H
class MyThread : public QThread
{
Q_OBJECT
virtual void run();
signals:
void returnVar(int *aPtr, int *bPtr);
public:
int *a;
int *b;
};
class MyClass : public QObject
{
Q_OBJECT
int a; // Is it considered stack or global?
void someFunc(int *aPtr, int *bPtr);
MyThread thread; // Is it OK to create thread objects like this or should I use heap only?
public:
MyClass();
public slots:
void varAdded(int *aPtr, int *bPtr);
};
#endif // MAIN_H
.cpp file:
#include <QCoreApplication>
#include <QDebug>
#include "main.h"
void MyThread::run()
{
qDebug() << "A in thread: " << *a << ", B in thread: " << *b;
emit returnVar(a, b);
}
MyClass::MyClass()
{
a = 1;
int b = 2;
someFunc(&a, &b);
//MyThread thread; // If i declare thread here program will crush because thread was destroyed while running
QObject::connect(&thread, SIGNAL(returnVar(int*, int*)), this, SLOT(varAdded(int*, int*)));
thread.a = &a;
thread.b = &b;
// Is current block considered alive when I start a thread?
// As far as I understand it it not alive any more. Am I right?
thread.start();
// If I give this block some time I can create stack thread object in constructor and it will work
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
void MyClass::someFunc(int *aPtr, int *bPtr)
{
// As far as I understand these objects will work fine anyway because calling block is alive.
// Am I right?
qDebug() << "A: " << *aPtr << ", B: " << *bPtr;
}
void MyClass::varAdded(int *aPtr, int *bPtr)
{
qDebug() << "A returned from thread: " << *aPtr << ", B returned from thread: " << *bPtr;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyClass myClass;
return a.exec();
}
My questins are:
Are a and thread stack or global objects?
Is it OK to declare thread objects as I did or should I create them only in heap?
Are a and b objects guaranted to live in thread?
Are a and b objects guaranted to live when they (their references) return from thread?
I appreciate any help.
Your MyClass has 2 instance variables: int a and MyThread thread. Lifetime of these is bound to MyClass'es lifetime. Hence, since you declare MyClass on stack in main function these two variables will live in the same scope.
Now, in MyClass'es constructor you initialize fields of MyThread with pointer to variable a which, as already shown, is a stack variable alive throughout the whole program runtime, and a local variable int b which will cease to exist (hence the pointer will be invalid and dereferencing it is an undefined behaviour) as soon as the constructor finishes running.
So:
a and thread are stack variables, but since their parent (MyClass instance) is declared in main scope of main function they will be valid for the whole duration of the program
I would say so, but I'm in no way Qt expert (quick search around the net suggests it's safe to declare Qt objects on stack as long as you know their lifetime).
No, b will go out of scope hence dereferencing pointer to it results in UB. Your program may work, but it's unsafe to do so.
What Qt guarantees is that what you pass as arguments to a signal is delivered to signal's receiver. From what I gathered by reading this article Qt will copy the arguments (so, if the arguments are classes they will be copy constructed) and dispatch the call to appropriate thread (if subscription was done from different thread than the one emiting the signal). This however does not prolong (or in any other way control) the lifetime of objects pointed to via your pointer - one should use shared_ptr<T> if you want guarantee that the object is delivered intact.

Why is a slot being called in receiver's thread even after using Qt::DirectConnection? How do I ensure that it is called in the other thread?

According to the documentation for Qt::ConnectionType in Qt5, using Qt::DirectConnection means that the slot for a given signal is called in the same thread as the signal itself, even if the object the slot belongs to lies in a different thread.
In my application, I am creating a server, and when a new connection is received, I create a new thread, a new QWebSocket object in it, and connect certain QWebSocket signals to slots defined in the class of the server (the same class where the connection is received and the thread is created).
However, though the thread is created successfully, the slot is being called in the main thread.
Here is a simpler example that simulates what I am doing, an MCVE:
Base.h file:
#ifndef BASE_H
#define BASE_H
#include<QThread>
#include<thread>
#include<QObject>
#include "emitcaller.h"
#include <QDebug>
class Base : public QObject
{
Q_OBJECT
public:
EmitCaller *emitCaller;
void create_thread();
void make_emit();
public slots:
void do_something();
};
#endif // BASE_H
This represents the server class. create_thread() is like the function when a new connection from a client is to be done. do_something() is the slot that needs to be executed when the QWebSocket receives a signal.
Base.cpp file:
#include "base.h"
#include "emitcaller.h"
#include<QEventLoop>
#include <mutex>
#include <condition_variable>
void Base::create_thread()
{
std::mutex mutex;
std::condition_variable cv;
std::thread t = std::thread([&](){
EmitCaller *ec = new EmitCaller;
this->emitCaller = ec;
qDebug() << "thread created, now in thread " << QThread::currentThread();
QObject::connect(ec,SIGNAL(my_signal()),this,SLOT(do_something()),Qt::DirectConnection);
cv.notify_all();
QEventLoop loop;
loop.exec();
});
std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock); //wait till connect() completes, so that signal sent is received after that
t.detach();
}
void Base::do_something()
{
qDebug() << "doing something in thread " << QThread::currentThread();
}
void Base::make_emit()
{
qDebug() << "called make_emit in thread " << QThread::currentThread();
emitCaller->do_emit();
}
Next, EmitCaller.h file:
#ifndef EMITCALLER_H
#define EMITCALLER_H
#include <QObject>
#include <QDebug>
class EmitCaller : public QObject
{
Q_OBJECT
public:
void do_emit();
signals:
void my_signal();
};
#endif // EMITCALLER_H
This is to simulate the QWebSocket. The my_signal() signal is the one that the QWebSocket in the program receives to call the do_something() slot. make_emit() is an extra function, just to ask the signal to be emitted, created only for the sake of this simplified example.
EmitCaller.cpp file:
#include "emitcaller.h"
void EmitCaller::do_emit()
{
emit my_signal();
}
main.cpp file:
#include <QApplication>
#include "base.h"
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Base b;
qDebug() << "main in thread " << QThread::currentThread();
b.create_thread();
b.make_emit();
return a.exec();
}
The output is as follows:
main in thread QThread(0xc20180)
thread created, now in thread QThread(0x7fb9680009e0)
called make_emit in thread QThread(0xc20180)
doing something in thread QThread(0xc20180)
Now, as per my understanding, the following happens:
create_thread() is called. The EmitCaller object (QWebSocket object) is created inside a new thread. Thus, the thread affinity of the object should be the new thread, and all signals sent from it should be from the new thread.
connect() is done using Qt::DirectConnection. So, the slot do_something() should be called in this new thread, even though its class object, b, lies in the main thread.
do_emit() is called on the object whose thread affinity is with the new thread, which should result in the behaviour expected as described above.
I expect the output to instead be:
main in thread QThread(0xc20180)
thread created, now in thread QThread(0x7fb9680009e0)
called make_emit in thread QThread(0xc20180)
doing something in thread QThread(0x7fb9680009e0)
A few additional points:
In my server program, I don't have a pointer pointing to the QWebSocket object. However, the signal there is generated when a new client connects. To send the signal myself, I have created a pointer to access the object.
I need to use std::thread, I cannot use QThread for this.
Why is the slot being called in the receiver's thread, instead of the
emitter's thread, even though Qt::DirectConnection is used?
If this is incorrect, where am I going wrong? (I am new to the signal-slot system of Qt).
If this cannot be done this way, how can I achieve the behaviour I want? I would like do_something() to run in a separate thread.
Thank you.
You have to consider 3 threads in your problem statement:
The thread the receiver lives in
The thread the sender lives in
The thread that is emitting the signal
Queued/BlockingQueued connections ensure that the slot will be executed in the receivers thread.
DirectConnection executes the slot in the current thread. This is not always the thread the sender lives in! In fact, there is no standard way to enforce running a slot in the sender's thread (because usually, the receiver's thread is what you want).
NB: AutoConnection uses QueuedConnection if the current thread and receiver thread are not the same, otherwise DirectConnection
To solve your problem, you could forcably switch to the sender's thread if you're on another thread, like this:
In EmitCaller, add
private: Q_INVOKABLE my_thread_do_emit() { do_emit(); }
Then in the implemetation:
void EmitCaller::do_emit()
{
if (this->thread() != QThread::currentThread()) {
QMetaObject::invokeMethod(this, "my_thread_do_emit", Qt::BlockingQueuedConnection);
} else {
emit my_signal();
}
}
However, I would suggest that you reconsider your design. It seems unusual to call a slot in a certain foreign thread. Maybe there is a problem in your thread affinity setup... (e.g. the receiver should live in the newly created thread)

Cannot use QtNetwork because application uses different Threads

A strange behavior occured in my application when I'm using QtNetwork. I can easily create the QTcpSever and QTcpSocket instance and everything runs fine, but when it comes to QTcpSocket::write() the following error occurs:
The error
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
What is strange to me: I have no idea what/where this QThread(0x7f66a0020e20) is and how to get influence on it (have a look at the debugging below)
The program
I'm extending my main application (which is a library) with a network support. I put the network services into an extra class.
here the excerpt of the main application/library, where my network support is created:
QThread *thread = new QThread;
wifi = new WirelessNet(0, thread);
wifi->moveToThread(thread);
connect(thread,SIGNAL(started()), wifi,SLOT(initWifi()));
thread->start();
the network class extension:
WirelessNet::WirelessNet(QObject *parent, QThread *comThread): QTcpServer(parent)
{
clientThread = comThread;
}
void WirelessNet::initWifi()
{
listen(QHostAddress::Any, 5220);
connect(this,SIGNAL(newConnection()),this,SLOT(connectionRequest()));
}
void WirelessNet::connectionRequest()
{
client = this->nextPendingConnection();
if(client)
connect(client, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
}
void WirelessNet:sendData(QByteArray msg)
{
if (client)
{
qDebug()<<"FIRST "<< client->thread() << " - " << this->thread() << "\n";
client->write(msg);
client->waitForBytesWritten();
qDebug()<<"LAST " << client->thread() << " - " << this->thread() << "\n";
}
}
(client and clientThread are class members: QTcpSocket*, QThread* respectively)
The debugging
Here is what the console prints out when it comes to the sendData() part:
FIRST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x7f66980022e0), parent's thread is QThread(0x7f66a0020be0), current thread is QThread(0x7f66a0020e20)
QSocketNotifier: Can only be used with threads started with QThread
LAST QThread(0x7f66a0020be0) - QThread(0x7f66a0020be0)
Concluding
In other words I have no idea on which object I should apply the moveToThread(). I already tried client->moveToThread(clientThread) aswell as this->moveToThread(clientThread). Unfortunately I don't see any additional objects to check on.
Has anyone an idea ?
You seem to be calling WirelessNet:sendData directly from the main thread. This causes everything inside that function to be run in the main thread as well. Your client lives in the new thread, and it is not thread-safe. It tries to create children, but current thread is different from the thread where client lives in. That is why you get that error message.
You can fix it simply by making WirelessNet:sendData a slot and call it via a signal from the main thread.
My guess is that the constructor of your class is called in the calling thread, while the thread itself runs in the run() method of your class. The solution would be to initialize QTcpServer at the beginning of your run() method, so that initialization and communication through that class is done in the very same thread.

c++ multithread [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
c++ multithread
I use c++ to implement a thread class. The code is in the following.
I initialize two objects, wish it will start two threads (I use pthread_self() to look the thread Id).
But the result shows that there is only one thread beside the main thread.
I am a bit confused...
class Thread {
public:
int mask;
pthread_t thread;
Thread( int );
void start();
static void * EntryPoint (void *);
void Run();
};
Thread::Thread( int a) {
mask =a;
}
void Thread::Run() {
cout<<"thread begin to run" <<endl;
cout <<" Thread Id is: "<< pthread_self() << endl; // the same thread Id.
}
void * Thread::EntryPoint(void * pthis) {
cout << "entry" <<endl;
Thread *pt = (Thread *) pthis;
pt->Run();
}
void Thread::start() {
pthread_create(&thread, NULL, EntryPoint, (void *)ThreadId );
pthread_join(thread, NULL);
}
int main() {
int input_array[8]={3,1,2,5,6,8,7,4};
Thread t1(1);
Thread t2(2);
t1.start();
t2.start()
}
You are seeing this behavior because you join with each of your threads immediately after you spawn them.
When you join with a thread, you block until the thread terminates.
You are spawning two threads, but the first thread is joined (and destroyed) before the second thread is spawned, so you have effectively only one thread running at a time. The way to fix this is:
Create a separate join function that invokes join().
Do not call join directly from your start() function.
In your join() function, be sure to mark the thread as having been joined/destroyed.
In your destructor, if your thread has not been joined, then you should detach it.
I should also point out that boost::thread provides cross-platform multithreading for C++.