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.
Related
I have an QThread which listen server. I want to pause work of QThread immediately. Not waiting at all, but almost like terminating, it must be immediate.
A code running in any given thread cannot be stopped at an arbitrary point without corrupting the state of the shared data structures in your code and/or the C/C++ runtime or any other libraries that are used.
The code can only stop at well-defined points.
If your thread runs an event loop (i.e. usually if you don't derive from QThread or don't override its run), then QThread::quit() will stop the thread once it returns control to the event loop, where it's safe to do so.
If your thread reimplements run and executes a loop there, it should return when interruption is requested:
void MyThread::run() {
while (! isInterruptionRequested()) {
...
}
}
Such a thread is stoppable by QThread::requestInterruption().
For reference, here are various methods of QThread that are sometimes confused:
wait() blocks the calling thread until the called thread finishes. Of course, calling it from within the thread itself is instant deadlock: a thread can't finish if it waits for something that's never going to happen.
quit() quits the thread's event loop at the earliest opportunity, and causes QThread::run() to return. It does nothing if you're reimplemented run() and don't spin an event loop.
requestTermination() sets a flag that a custom loop in YourThread::run() can check via isTerminationRequested().
terminate() stops the thread now. This generally corrupts the state of your application, so you must abort() sometime soon or face the consequences. This method is best forgotten about. It essentially means "crash this process soon and corrupt some disk data if you get a chance".
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 two QObject child classes in my Qt application. One object from each of these classes was instantiated on the stack. Previously, my application would exit cleanly. However, since I've updated to Qt5.1.0, their destructors are not being called. I get the following warning twice when I launch the debugger.
the debug information found in "/usr/lib/debug//lib64/libfreebl3.so.debug"
does not match "/lib64/libfreebl3.so" (CRC mismatch)
Is this a bug in Qt or in my code?
See the documentation of QCoreApplication::exec:
We recommend that you connect clean-up code to the aboutToQuit() signal, instead of putting it in your application's main() function because on some platforms the QCoreApplication::exec() call may not return. For example, on Windows when the user logs off, the system terminates the process after Qt closes all top-level windows. Hence, there is no guarantee that the application will have time to exit its event loop and execute code at the end of the main() function after the QCoreApplication::exec() call.
You're using it incorrectly. It is not guaranteed that exec will be terminated after windows are closed. You should use aboutToQuit signal to stop other threads. If this signal is not emitted either, you need to call QApplication::quit() explicitly when your window is closed.
I'm not exactly sure in this case if this is a bug in your code or not, but anyway it is not recommended to create QObjects in the stack.
The reason is that the parent object (if any) will automatically call delete when destroyed, but then the object will also be automatically destroyed when it goes out of scope. Hence the object is destroyed twice which is Undefined Behaviour. That may explained why it worked well in one case, and not in another, since you can't rely on any consistent behaviour.
(But in your case it is weird that you say the destructor is not called at all...)
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.
I was digging into some source code I am working on. I found a peculiar statement that someone had coded. The source code is a GUI application with a QML GUI and uses QT 4.7.x.
The snippet below belongs to core application logic.
// connect signal-slots for decoupling
QObject::connect (this, SIGNAL(setCurrentTaskSignal(int)), this,
SLOT(SetCurrentTaskSlot(int)), Qt::QueuedConnection);
It's strange that the object connects to itself via a queued connection which essentially means that the object may "live" in different threads at the same time?
At first glance It didn't made any sense to me. Can anyone think of any reason why such a connection would be plausible or needed?. Would this even work?
It will work without any problem. Maybe there was some event loop processing required before calling SetCurrentTaskSlot?
Note that QueuedConnection doesn't mean that something is in different thread. QueuedConnection means only that when signal is emitted, corresponding slot won't be called directly. It will be queued on event loop, and will be processed when control will be given back to event loop
The queued connection implies nothing about where the receiver lives. The opposite is true: to safely send signals to an object living in another thread, you must use queued connections. But you can use them for an object living in any thread!
One uses a queued connection to ensure that the signal will be delivered from within the event loop, and not immediately from the emit site as happens with direct connection. Direct connection is conceptually a set of calls to function pointers on a list. Queued connection is conceptually an event sent to a clever receiver who can execute a function call based on the contents of the event.
The event is the internal QMetaCallEvent, and it is QObject::event that acts upon this event and executes the call.