QProcess doesn't kill/terminate the process if be defined on heap - c++

I want to kill/terminate the process that's I created when my app exit:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QPushButton w; w.show();
struct Lambda {
static void run() {
static QProcess p; //version 1
// QProcess& p = *new QProcess(qApp); //version 2
p.connect(qApp, &QApplication::aboutToQuit, &p, &QProcess::kill);
p.connect(qApp, &QApplication::aboutToQuit, &p, &QProcess::terminate);
p.connect(qApp, &QApplication::aboutToQuit, &p, &QProcess::close);
p.connect(qApp, &QApplication::aboutToQuit, &p, &QProcess::deleteLater);
p.start("caffeinate -d");
}
};
QtConcurrent::run(Lambda::run);
return a.exec();
}
With version 1: my app run as I'm expecting: create and kill the process successfully but when exit the app, QCreator report: "QProcess: Destroyed while process ("caffeinate") is still running."
With version 2: my app can start the process but cannot kill/terminate the process on exit, and there are no report like above.
I just want to ask why when created on the heap, QProcess cannot be kill like stative version? Thanks!
(I used struct Lambda because of I cannot use c++11 lambda in my project)

tl;dr
In both cases, the signals aren't delivered; in the first case the destructor kills the process, in the second one it doesn't even have a chance to run.
In general, your code is a nice compendium of almost all the no-dos with QObject, QThread, signals and the like; do read Threads and QObjects before doing anything with threads, QObjects and signals in Qt. This is essential information without which you'll only do a mess like this.* Also this wiki article provides a good rundown of the "right way" to use threads with Qt.
Detailed explanation
Let's call the main thread thread A and the thread started by QtConcurrent::run thread B.
Case 1
When run is run from the second thread, p is created, so it has thread affinity with thread B. For this reason, all the connect you perform on it are queued connections (the default for connect is AutoConnection, which uses a QueuedConnection if the connected objects have different thread affinity - and qApp is created in thread A).
The problem is, queued connections work only if the receiving thread has an event loop running (they are implemented as a sendEvent, so if there's no event loop processing events in the target thread they only pile up in the event queue), while here run returns right after starting the process.
So, kill, terminate, close and deleteLater are never called. Notice that:
calling deleteLater in this case would have been an error anyway, since it would be trying to do a delete on a static object;
neither kill nor terminate are synchronous, so to make sure that the process is dead before going on you would have needed also a waitForFinished;
also, potentially the thread that has been spun by QtConcurrent::run is going to be dead after run terminates1; this is definitely a bad thing, because you are going to have QObjects laying around with thread affinity to a thread that is dead. I don't know how gracefully sendEvent handles this situation.
Anyhow, when the program ends, the p's destructor is invoked automatically as a normal part of the shutdown of a C++ application2; as documented, the destructor of QProcess terminates the process it is linked to if it's still running (but also writes out the "scary message" you saw).
Case 2
As in case 1, you are creating the QProcess with thread B affinity; so all that we said above about events not being delivered & co. still applies.
There are three main differences here:
you are setting the parent of p to qApp, which lives in the main thread; this is explicitly disallowed, all parent-child relationships between QObjects must exist between objects with the same thread affinity; probably you are getting some warning message in console about this fact (setParent explicitly checks if the objects live in the same thread, I expect QObject's constructor to do the same);
in this case, the deleteLater could have been appropriate (if you had an event loop spinning), as you allocated with new;
but most importantly, here p's destructor is never invoked, as it has been allocated with new and no one is calling delete on it; for this reason, the started process keeps running (also, you have a small memory leak).
So, what would have been the been the correct way to deal with this? Personally, I would have avoided threads and signals altogether. The starting a process is already asynchronous so you could have simply done:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QProcess p;
p.start("caffeinate -d");
QPushButton w; w.show();
int ret = a.exec();
p.close();
return ret;
}
as always with threads, event queues, signals and the like: don't make it more complicated than it needs to be.
Footnotes
In practice in this case you probably won't notice because QtConcurrent uses the global thread pool, which kills spun threads only after 30 seconds of idling.
General tip: you typically don't want "complicated" objects to be destroyed in this way, since the main has already terminated, so (1) this makes debugging more complicated and (2) if you have Qt objects that depend on the QApplication still being alive (typically, everything in QtGui and QtWidgets) you'll start to get weird crashes at program termination.

Related

QApplication::processEvents on a different thread

I have a couple questions.
Is it possible to initialize a QApplication object on one thread and destroy it on another?
Why does QApplication have to run on the same thread in which it was allocated?
Is it possible to run QApplication::processEvents() on a different thread from where the QApplication object was created? Will this work if the thread to call processEvents was a non-QT thread?
It may be possible but Qt is not tested for it. I imagine that it's possible to hack that in - you'd need code changes. It won't ever work on MacOS, unless you're having only QCoreApplication in mind - neither the QApp.. nor QGuiApp.. supports other threads on that platform, and possibly on other platforms as well (Windows excepted). I have no idea why would you do that, though. Once the QApplication event loop is running on the given thread, it can terminate on command and automatically destroy the application instance. In fact, it's trivial:
int main(int argc, char *argv[]) {
QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));
QtConcurrent::run([]{
// this runs in a worker thread, and causes the application
// object to destroy itself and then the program to exit
QThread::sleep(2);
QCoreApplication::quit();
});
auto rc = app.exec();
app.reset();
// perhaps do some other processing here that doesn't need
// a qApp instance
return rc;
}
Why not? QApplication doesn't have to "run" at all, so who cares? You can run an event loop on any thread, and the one in the main thread doesn't need to run at all unless you have some objects in the main thread that you want to deliver events to. The event loop in the main thread is special because that's the only one where QWidget instances are supported. That's a Mac OS limitation, so if you want to write portable code, you can only instantiate QApplication on the main thread (i.e. something that has int main() on the call stack).
Yes, with the caveat that it doesn't do what you likely think it might be doing. The meaning of QCoreApplication::processEvents means "drain the event queue of the current thread". In Qt, an event loop is a per-thread resource. You can run an event loop on any thread - in fact, QThread::run does precisely that: its run() does, in essence QEventLoop().exec().
And you can only drain the event loop of whatever thread you're in, because there's no access provided to any other event loop - it wouldn't make sense: "draining" an event queue means dispatching events in the thread of the event loop that runs on that queue, and when you execute in any given thread, you by definition aren't executing code in some other thread and thus can't drain the event queue there. QCoreApplication::processEvents is equivalent to QAbstractEventDispatcher::instance()->processEvents(), where instance() is the event dispatcher instance in the current thread.
Now you might say: But hey, what if we could take the event queue data that belongs to some other thread, and invoke all those QObject::event methods in another thread? This is not only not designed to ever work, you're might simply deadlock on internal Qt mutexes and that'd be the end of it. There's no point to it anyway. On most any platform, you can send the equivalent of an interruptible sleep signal to any thread, and inject a code to execute - i.e. QCoreApplication::processEvents - within that signal. On Windows, you'd use APCs for it, on Unix it'd be some combination of signals and other clever code. It is possible to emulate APCs to an extent by doing stack inspection to determine whether the context is safe, and if so doing things that would not otherwise be allowed.
There's no such thing as a "non-Qt" thread. A thread is a platform resource, by definition. QThread is not a "Qt" thread. It's a handle to the platform's thread resource. Even better: it's a handle that's automatically created when there's a demand for it, so you can always refer to the current thread, even if your code hasn't created such a handle explicitly before.
Perhaps you need to tell us what you're trying to do. There's something very fundamental that's missing in your question.

Confusion regarding QThread, QObject, Thread Affinity and Event Loop

I was going through the links
You are doing it wrong
Using QThread in right way Part1
Using QThread in right way Part2
I got confused by some statements. In the first link, it says that
all of the functions in QThread were written and intended to be called from the creating thread, not the thread that QThread starts.
while it suggests to use moveToThread to move an object to new thread, instead of subclassing QThread. My question is:
The default implementation of run method calls exec, which creates an event loop, and when an object's thread affinity is changed using moveToThread, all the slots will be executed in the new thread, not on the creating thread, which is contradictory with the aforementioned intended use. Am I missing something?
Second question:
In the third link it is said
event queue is belong to thread instead of event loop, and it’s shared by all the event loops running in this thread.
My question is how there can be more than one event loop in a single thread ? What I understand is, event-loop loop through the event-queue, until exit/terminate is called, and processes each event arrives on that queue. If this is true, one loop will never end (unless exit/terminate is called), how another can begin? Any sample code demonstrating it will be highly appreciated.
"which is contradictory with the aforementioned intended use. Am I missing something?"
Yes, I think you're misunderstanding the concept of thread affinity (the thread on which an object is running).
Let's take an example with minimal code: -
QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread); // MyObject on the new thread, controlled by pThread
pThread->start(); // pThread instance is still on the main thread
Assuming this code has been created from an object whose thread affinity is the main thread, such as QMainWindow, the thread object pThread is running on the main thread; it's thread affinity is the main thread.
In contrast, the QObject derived MyObject instance, myObj, has been moved to the new thread pThread. So, the thread affinity of myObj is now the new thread.
The "functions written for QThread" are still called directly from the main thread, as that's where it's running.
Think of QThread as a thread controller object, rather than the thread itself. This is one of the reasons why it is often discouraged to inherit from QThread, unless you want to change how QThread manages the underlying thread.
how there can be more than one event loop in a single thread ?...
I've not used this directly myself, but I'll try to explain this as I understand it. Perhaps someone else will be able to correct or confirm this. From the Qt Documentation for QEventLoop, it states: -
At any time, you can create a QEventLoop object and call exec() on it to start a local event loop.
The signature from QEventLoop exec is: -
int QEventLoop::exec ( ProcessEventsFlags flags = AllEvents )
So if you pass in a set of flags, only these events would be handled. Now, as calling exec() starts the processing of events until exit() is called, you can create a local event loop that lets your program wait until one or more specific events occur.
A second event loop is a local event loop within the main event loop, but as each event loop can process the whole event queue, which is shared by all event loops in a thread, it can be used to override event handling from the main event loop.
If you conceptualise an event loop as doing something like this (pseudo code): -
QList<QEvent*> eventList;
while(!stop)
{
// handle events in eventList
}
A 2nd event loop would then do this: -
bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
// handle events in eventList
...
...
// Inner event loop
bool bStop = false;
while(!bStop)
{
// handle events in eventList
}
}

QThread: If there is no run() implemented, what does it do while waiting for signal?

First of all, I am not using a GUI. (In case that matters.) I want to send the path of a file to a thread (as char*), have it process the file, then return. Preferably, I would like the thread to stop when it's not being used.
The Qt documentation shows two approaches to creating threads:
Create a QObject and moveToThread().
Create a QThread then start() it when it's needed.
In the two approaches above, what is happening if I don't have a run() function? I don't have one because I don't see a way of passing the char* to run(), so I'm using a signal. Do I have to start() the thread in order for it to work properly? If so, what does this do if there is no run()? Can I just create it, connect the signals/slots, then call it when I need it? Does one of the above approaches offer an advantage in this case?
UPDATE: Thank you for the quick response Johannes Schaub and thuga.
If I'm using QObject->moveToThread(), that thread is then running in an event loop? And this event loop sleeps when there is no input? (If so, that's good.) The thread (event loop) is tied to QObject's signals and slots, right? So I need to then have this object's scope be the calling thread by putting it in the constructor? (And quit() wait() in the destructor) It therefore runs for the entire lifetime of the original thread?
I don't think I need to have a slot for the QThread, because I only want to invoke it, not communicate back and forth. (Except the finished signal.) So I would do something like this:
a. Create an instance of the QThread:
WorkerThread *workerThread = new WorkerThread(this);
b. Send it the string. This is the part I'm not sure about. I think Johannes tried to explain, but I'm still not clear. I can't send the filename via a signal/slot because QThreads shouldn't use slots. (but can in moveToThread() case because of queued connections)
c. Start the Thread with .start()
The default run function then calls exec, which enters an event loop. The loop sleeps if it doesnt have an event to process.
The object that you move to the thread is not the QThread object itself. It is another object. The QThread object itself just has the event loop and is still associated with the main thread (its affinity is the main thread).
If the thread operates in the background, you best use QString as the filename and then call a respective "processFile" function or similar of that object that you pass the file name. The invocation can either be by a signal slot connection or an explicit QMetaObject::invokeMethod, using the connection type QueuedConnection (which passes an event into the event loop of the thread of the object, so your file names are automagically queued by being contained in that internal slot call event).
If I'm using QObject->moveToThread(), that thread is then running in an event loop?
Those are completely unrelated. A bare QThread is running the event loop as soon as you start() it. For this to happen you don't need to move any objects to it. Of course the event loop is dormant since there are no incoming events for it to process - so the thread, in spite of having been started, doesn't consume any CPU.
The thread (event loop) is tied to QObject's signals and slots, right?
Signals and slots are simply function call sources and sinks that you can link up. They have not much to do with event loops.
When the sender and receiver objects reside in different threads, the delivery of a slot call is implemented by posting a QMetaCallEvent to the object's event queue. That even, like all events, is given to QObject::event(QEvent*) method. That method acts on the QMetaCallEvent and executes the slot call.
So I need to then have this Object's scope be the calling thread by putting it in the constructor? (And quit() wait() in the destructor) It therefore runs for the entire lifetime of the original thread?
The object's lifetime is decoupled from thread's lifetime. An object that is moved to a given thread can only be destructed from that thread. If the thread terminates first, the object becomes threadless (its thread() returns nullptr), and it can be destructed from any thread, or moved to another thread. A threadless object can't receive any events, but of course it can receive direct slot calls. Queued slot calls won't work since those are delivered as events initially, and only internally converted into calls.
I don't think I need to have a slot for the QThread, because I only want to invoke it, not communicate back and forth.
A QThread is a thread controller. There's very little reason to subclass it. In almost all cases you can either use a QObject that has been moved to the thread, or QtConcurrent::run.
So I would do something like this: [...] Create an instance of the QThread: [...] Send it the string.
You want to send the string to an object that lives in the thread, not to the thread itself.
Here's a small example:
// main.cpp
#include <QThread>
#include <QCoreApplication>
#include <QDebug>
class Worker : public QObject {
public:
Q_SLOT void say(const QString & str) { qDebug() << str; }
};
/// A thread that's safe to destruct at any time.
class Thread : public QThred {
using QThread::run;
public:
~QThread() { quit(); wait(); }
};
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
Worker worker;
Thread thread;
thread.start();
worker.moveToThread(&thread);
// Equivalent to invoking the say slot from a signal
QMetaObject::invokeMethod(&worker, "say", Q_ARG(QString, "hello"));
//
QMetaObject::invokeMethod(&app, "quit");
return app.exec();
}
#include "main.moc"
It sounds like your thread is supposed to process a char* and then wait. If this is the case, there's a third option available to you where you have a single function that runs in a separate thread and then exits, using QtConcurrent::run()
Simple example:
void workerFunction(QString const &data){
// ...
}
void callingFunction(){
// ....
char *data = .....;
QFuture<void> future = QtConcurrent::run(workerFunction, QString(data));
}
EDIT:
If you need more features than a single threaded function but not as many as a fully-fledged subclass of QThread, there is also the QRunnable/QThreadPool pair as a convenient intermediate option.

Threads inside a qt class

I have this class inside a qt application that has some data defined:
class TableView:public QWidget
{
Q_OBJECT
public:TableView (QWidget * parent = 0);
std::vector < float > arr;
and some class functions and so on..
Now I want to add a socket server in another thread (posibly from inside this class) that is able to access data from this class when it recives something from the socket, calculate
new data and return.
For the test I used:
//defines
DWORD WINAPI SocketHandler(void* lp);
DWORD WINAPI starttremeshserver(void* lp);
CreateThread(0,0,&starttremeshserver, (void*)csock , 0,0);
This works. Now I need something easy and platform independent. Maybe something with qthread since I am working in qt.
So the question is, can I make a new thread function inside a class that can access class data. ty
Qt provides everything you need. Your needs are as follows:
Thread-safe (serialized) access to the data members of the TableView class.
Networking primitives.
Flexibility to move network access to a separate thread.
You are probably receiving data from the network, and want to update the arr member. You'd do it like so:
Create a QObject-derived class, say Processor, that has a slot that sets up the network connection (probably a QTcpServer). Upon a connection, use QTcpSocket to exchange data. Make sure all your data handling is done in slots in the class. When you have new values to update in the vector, simply emit some signal, like hasFloat(int,float).
Add a setFloat(int,float) slot in the TableView.
Connect the setFloat signal from the instance of Processor to your TableView.
At this point, everything runs in the GUI thread, but the code is non-blocking since you never wait for network data; you respond to the signals emitted by QTcpServer and QTcpSocket. You can leave it like that if you wish.
Having the Processor class run in a separate thread, if your benchmarking shows that your main thread is CPU bound, is then trivial:
int main(int argc, char** argv) {
bool separateThread = true;
QApplication app(argc, argv);
TableView view;
Processor proc;
connect(&proc, SIGNAL(hasFloat(int,float)), &view, SLOT(setFloat(int,float)));
QThread thread;
if (separateThread) {
thread.start();
proc.moveToThread(&thread);
}
view.show();
const bool rc = app.exec();
if (thread.isRunning()) {
thread.exit(); // tells the event loop in the thread to bail out
thread.wait(); // waits for the above to finish
}
return rc;
}
There's this misconception that spreading things across threads somehow magically makes them better. Threads are a solution to a particular problem: CPU-boundedness of the computations being done, and blocking APIs. If your processing is trivial, you are not likely to be CPU bound. Qt provides nonblocking, asynchronous networking. Thus, usually, spinning a second thread is entirely unnecessary.
You must show real numbers first to show you otherwise. Else you're buying into the cargo cult of threading: oh, it's networking, it must go into a separate thread. Nope, not necessarily. Measure first. Understand what you're doing.
The reason for thread safety in the above code is as follows: when you move the Processor instance to a different thread, Qt will reconnect all signal-slot connections using Qt::QueuedConnection type. Thus, when Processor emits hasFloat, it will internally cause an event to be queued in the event queue of the thread where TableView lives -- the GUI thread, in this case. When the event loop spins (here it'd be the application's event loop) -- it'll pick up the event and execute a call to TableView::setFloat. This ensures that the access to the arr data member is serialized and there are is no possibility of concurrent access from multiple threads.
I'd personally look for more high level socket support, something based on boost perhaps, anyway for threads you can use <thread> in C++11.
To answer your specific question:
class Foo
{
private:
void spinthread()
{
thread t([this] {
this->bar = 12;
});
}
private:
int bar;
}
If you're using Win32 threads API, the thread proc has a parameter which you can use to pass your instance to during the CreateThread call.
Qt has threading support as can be found here.
In addition to threads and accessing the data, you'll need synchronization for thread-safe code. This is called pthread mutex in linux, and in Qt its called QMutex as mentioned here.
You can find the Qt networking primitives here.
Using the Qt implementation of these threading and networking primitives will be portable, so should work for you on windows.
Regarding your question about creating a thread function from a class that accesses data on that class, the answer is yes. Instead of creating a thread function, it would be better to create a thread object, namely a QThread. When you create the thread object, you'll need to pass a reference to the instance of said class, which will allow the thread to access the class instance.

Questions about implementing QThread in my application?

As suggested in this question, I am now trying to incorporate multithreading.
According to the links given by karlphillip, I understand that the documentation about subclassing QThread is not to be followed and to use moveToThread() as explained. Now I see that default implementation of QThread run() has only an exec() which must then be ended by calling quit() when worker thread has finished operations. I have a few questions now so that I understand things better:
QApplication* ptrApp=new QApplication(argc,argv);
QThread* th=new QThread;
MyClass* obj=new MyClass;
obj->moveToThread(th);
QObject::connect(th,SIGNAL(started()),obj,SLOT(someFunct()));
QObject::connect(obj,SIGNAL(over()),th,SLOT(quit()));
th->start();
//some GUI code in main thread here
return ptrApp->exec();
What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?
Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)? My understanding is: it cannot be in th when I have quit() that thread... quit() will be queued until the exec() in the main thread executes it which will cause the exec() in run() of th to exit (I hope I am not making a mistake here). I assume that thread is no longer existent.
Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?
It doesn't matter if the event loop is terminated, somefunct() will continue to run until it gives control back to the now extinct loop.
obj stays associated to the thread, so if a signal connected to one of its slots is emitted, the slot won't run but it will be queued for when/if the thread is restarted.
If the QThread object is deleted, obj->thread() returns 0, so I suppose this would be equivalent to calling obj->moveToThread(0) and according to the documentation:
If targetThread is zero, all event processing for this object and its children stops.
quit() terminates the event loop, then the finished() signal is emitted from the thread, and the thread terminates.
So, even when you receive the finished() signal, you shouldn't assume that the thread is finished yet. You can use QThread::wait from the main thread, after you receive that signal to ensure that.
If the thread is in the finishing state, the QThread destructor already calls wait, so you can safely delete the thread after the finished() signal (with deleteLater() to be even safer).
1. What happens if I continue to use someFunct() even after I emit over() from within someFunct()? Is it undefined behaviour or normal?
As you are using direct connections, emitting over will call directly the function quit, which stops the event loop and return from the exec in the thread run method. Which means someFunct() will not finish its execution and the objects inside it are either lost or in a partial modified state.
2. Which thread would obj now be associated with (while the rest of the code after emitting over() is still executing in someFunct)?
As said previously somefunct will not finish its execution. But I believe any objects associated with this thread will remain as such. I say I believe because there is no solid assertion anywhere, but it make sense the most. As mentioned in the doc, for these objects to send or receive events the thread must be started again....
3. Once slot quit() for th is executed, is it safe to assume that the thread has indeed quit or should I further connect finished() signal of th to some slot to be absolutely sure?
quit() terminates the event loop and return where exec() was called.
Notice that the object Qthread is not the thread. so until you enter exec(), it is the main thread which is running... As well as it is the main thread which runs after the exec.
Anyway these are some great questions...