I'm an advanced beginner using Qt and I'm trying to write a console app that uses QFtp. The app itself is essentially just procedural code but because QFtp is asynchronous this is driving me crazy. I need to test that multiple ftp downloads are successful, but the code doesn't block so the test always fails. The best solution so far is to create a chain of signals and slots daisy chaining the ftp code and the procedural sections. It seems there has to be a better way. Any ideas?
You can use QEventLoop to wait for a signal. Just connnect the signal to QEventLoop::quit(), and then call QEventLoop::exec().
QFtp ftp;
QEventLoop eventLoop;
connect(&ftp, SIGNAL(commandFinished(int,bool)), &eventLoop, SLOT(quit()));
eventLoop.exec();
As it's asynchronous you're best off tracking it through the signal and slots mechanism, but that does throw off your procedural logic. The only other default option for FTP in Qt is QNetworkAccessManager but that's also asynchronous, so whichever you go for you're going to have to use the signal/slots system to track when it's done.
You could use QTcpSocket and write your own FTP code, that allows you to block the calling thread until it returns with certain conditions, but you'll have to write significantly more code to do what you want to.
Related
I am developing an application that uses QSerialPort to receive data via uart. In this application I use a log function that writes to a file. Before writing to the file the application locks a mutex and after writing to the file it unlocks the mutex. Between mutex lock and unlock I am not calling the log function again.
Of course the data coming from serial port arrives asynchronously and it triggers a signal and a slot where the data is processed. In this function where the data is processed I am calling the log function again.
I am not using multithreading in my application, as far as I know the slots are called in the same thread.
The question is: can the single thread deadlock itself when the data from QSerialPort arrives exactly after the mutex in the log function was locked ? (This would mean a double lock of the same mutex - assume we do not use a recursive mutex)
Is there a good source of knowledge about such a topic ?
If your serial port gets data exactly after the mutex locked it will not execute immediatly (because this is not interruption) but it wait when QEventLoop will execute a receiving data slot (in global event loop). You can execute all events manually with qApp->processEvents() so try to avoid it inside lock/unlock block.
If you use explicit calling of log function in single thread you will not have a deadlock (I think). But be carefull with writing a log via qDebug() macro with reimplementing qInstallMessageHandler because you can forget and use qDebug() inside mutex lock/unlock block. Then you will have a deadlock.
Also it could be some troubles with callback functions inside your lock/unlock block. So be carefull with callbacks too.
i am getting QObject::startTimer: Timers cannot be started from another thread from this snippet and it's blocking my application and freezing the UI. I am kind of new to threading in QT.
void ReportModel::myslot(){
moveToThread(&thread);
connect(&thread, SIGNAL(started()), this, SLOT(exportProg()));
thread.start();
}
in exportProg() i am making a csv file in pendrive.
Given that ReportModel is likely a class used from the GUI thread, this won't work and is a bad idea. this->moveToThread(...) is usually a bad code smell unless you know exactly what you're doing.
Why are you moving the model to a thread in a slot? Shouldn't it be in a thread from the very beginning? Why are you connecting slots to the started signal? The idiom for job submittal to the current object thread's event loop can be QTimer::singleShot(0, ...) or QMetaObject::invoke, and that works without any dependency on a thread starting at that very moment. Most likely, exportProg should be a threadsafe method that can be submitted for asynchronous execution via QtConcurrent::run.
I've read there are two approaches for working with QThread.
If I have a Worker class, which inherits QObject (as in http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/), then how should I create and manage local QEventLoop for working with signals/slots? I don't want to have memory leaks.
How QNetworkAccessManager should be created in worker described in http://codethis.wordpress.com/2011/04/04/using-qthread-without-subclassing/?
If you don't subclass QThread, it has its own event loop (Fixed QThread documentation of Qt 5, also appliccable for Qt 4):
By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.
Managing the work done by the worker can be easily done using signals & slots:
(...) you are free to connect the Worker's slots to any signal, from any object, in any thread. It is safe to connect signals and slots across different threads, thanks to a mechanism called queued connections.
This means you usually don't need to care about any event loop on your own (unless you require special behaviour). Simply connect the thread's started signal to any slot of your worker object and make sure you set up some kind of deletion chain: Either the worker emits a signal which leads to the thread being stopped and deleted, or the other way round - both ways work, depending on your situation.
I have several client GUI windows all derived from QMainWindow. Each window is potentially doing a different task but all are requesting data from a central cache implemented as a QThread.
All the clients connect to the same slot in the data cache and then emit signals to prompt the data cache to do something. The signals to the data cache get queued so the data cache only ever does one thing at a time.
When the data cache completes it needs to inform the correct client that the thing it was doing has completed. My immediate thought is to emit a signal to the requesting client about the completion. This would mean connecting to a specific client's slot and then emitting a signal to it.
Do I have to do connect and then disconnect to the client? I'm aware of the QObject::sender() function to get the supplier. Is there some way of emitting a signal to that sender (client) only? Or is there some other way of doing this?
There may be simpler approaches you can take to resolve your problem. For example, I would consider looking into the QtConcurrent framework. Alternately, you might also re-architect your design such that the client first connects to a "finished" signal on the cache prior to asking the cache to do anything. Failing all of that, you might also consider relying on the QMetaObject::invokeMethod function (for either your client or your cache). This function allows you to call an arbitrary method on an arbitrary QObject (provided that you have a pointer to it) using arbitrary generic arguments (in a way that's thread-safe).
If you use the QMetaObject::invokeMethod approach, there are a few of drawbacks you should be aware of. Firstly, you have to invoke the method using its string name, which means that you won't find out at compile time if you're using the wrong name. Secondly, since your clients have a different thread affinity than the central cache, there's a chance that the client will have been destroyed when the cache invokes the method on them (though perhaps in your case, this won't be a problem for you). Finally, you may not want your cache to have any knowledge of the names of the methods that it must execute on its client.
I don't have any way of getting around the first drawback (I'm not sure if this is going to be handled differently in the upcoming Qt 5.0 release). As far as the second and third problems, I would recommend creating an object that encapsulates a reference to a method -- something like the following:
class MethodReference
{
MethodReference(QObject* object, const QString& methodName);
...
bool invoke(QGenericArgument val0 = QGenericArgument(),
QGenericArgument val1 = QGenericArgument(),
...
QGenericArgument val9 = QGenericArgument());
private:
QPointer<QObject> mObject;
QString mMethod;
};
You would then pass this object to your cache from the client. The cache then calls invoke on this object.
Note the use of QPointer -- this gives you a thread-safe way of checking if your object has been destroyed before you try to invoke a method on it. Since I've done this before, I'll also let you know that versions of Qt prior to 4.8 had a bug in QPointer that would cause a crash in a multi-threaded context. Use a more recent version of Qt if you want to do this.
I hope this was clear.
I am trying to use Qt as a library (similar to this), because I want to reuse Qt classes in some currently non-Qt applications, and in shared libraries as cross-platform glue. Everything is non-GUI.
Some problems are easily avoided by DirectConnection, some can be solved with private event loops, even one can run a fake QCoreApplication in a thread and it works (last resort).
I want to know what modules rely on a running instance of QCoreApplication and cannot work without it.
Some of the Qt modules (in QtCore) do need an instance of QCoreApplication to run properly. For example QTimer relies on QCoreApplication to dispatch timer events.
I was reading the documentation for QtConcurrentRun and it seems to be relying on a global instance of QThreadPool, I am about to try and see if the application execution is vital, or maybe the instance is created on first access, or maybe not.
I am going to study QCoreApplicationPrivate source (Windows and Linux for now) but any hints in the right direction is greatly appreciated.
What are other functionality dependencies to the core application? Note that it might depend on the OS.
Edit1: Thanks to Kuba's answer, It seems QCoreApplication event loop is not necessary for timer and socket events to be dispatched. So some QtCore modules require and instance of QCoreApplication, but there is no need to have a running application event loop.
You are conflating the existence of a QCoreApplication with a running event loop. Those two are separate concepts. You may well need the former for the latter, but the latter doesn't have to run in the same thread as the former.
Most notably, you don't really have to call qApp->exec() if you don't have any events to dispatch in the thread where you constructed QCoreApplication.
The existence of a QCoreApplication is, as it were, a non-issue. Things get hairier with QApplication -- you can start it in a non-gui thread, but it's not portable and won't work on OS X. I'm trying to figure out why it doesn't work, but I don't have much time now to offer a satisfactory solution -- not yet.
It is also a misconception that QCoreApplication's event loop needs to be running for socket notifications and timer events to be dispatched to other threads. A QCoreApplication's event loop is nothing special. There is a platform-specific instance of QAbstractEventDispatcher that gets created for a thread when you instantiate the first QEventLoop in that thread. The QEventLoop doesn't know anything specific about the platform.
QCoreApplication's exec() method is quite simple and creates an instance of QEventLoop, and thus will create an instance of platform-specific QAbstractEventDispatcher. This instance is not special in any way. It's the same as any other event dispatcher created in any other thread, as far as my code reading tells so far.
If all underlying window systems would support it, it'd be in fact possible to make Qt GUI code multithreaded -- the per-thread event reception and dispatch is already there as a small first step. The big obstacle, probably the only one, would be the X library and its display lock. The display lock would be an obvious matter of contention between threads. You'd need each thread that wants to talk to the GUI open up a separate connection to the X server, and I don't know if there's a supported way of doing that from Xlib.