1

In my application I have the need to use 4 threads. There is the GUI thread (which only handles GUI related stuff), the second thread (Sensor Thread) is responsible for receiving and filtering some sensor data from a network socket, the third (Control Thread) and forth thread (AI thread) handles some heavy work. To communicate between them I'm using signals and slots.

After the second thread has finished filtering the last received data it emits a signal with the data to the other 3 threads.

My problem is that it takes more than 5ms (timing is very crucial for this application) for the Sensor thread to emit the signal. But that does not happen when the AI and Control threads aren't connected.

I am already using QueuedConnection (default) and passing the data as a const pointer. The data is an object of a class I'm using and the size of it is about 1.2Kb (got it using sizeof(ClassData) )

The slots doesn't do heavy computation, it just updates the data in the current thread.

The code that emits the data looks like this:

void filterData()
{
    filteredData = filter(networkData); // Filters the network data

    // Emits a signal with the filtered data

    QElapsedTimer measureTime; measureTime.start();
    emit sendFilteredData(filteredData);
    qDebug() << measureTime.nsecsElapsed()/1e6; // Shows measured time in ms    
}
vahancho
  • 20,808
  • 3
  • 47
  • 55
  • 1
    What do you mean by `"it takes more than 5ms ... for the Sensor thread to emit the signal"` -- how are you measuring that? Or do you mean there is a delay of 5ms between emitting the signal and the corresponding slot(s) being called? Note that queued connections make use of the event loop so if the receiving thread is busy with a lot of events already queued then there will be some delay. – G.M. Dec 05 '19 at 14:10
  • I doesn't matter if you are passing `const& object` or `object` to QueuedConnection, as in that case data is always copied (to be sure that when data is passed between threads nothing odd will happen with source - you will have dangling reference). If you have multiple connections, data is copied multiple times. You can try to use come Qt like containers to avoid copying (COW property should be enough, but I am not sure). Moreover each queued connection is handled in order, so maybe you have a lot of communication when AI and Control Threads are connected (plenty emits, and slots are called). – bialy Dec 05 '19 at 14:14
  • 1
    Please put the code in your question rather than as a comment. – G.M. Dec 05 '19 at 14:23
  • Do you run your application in debug mode, or optimized one? – vahancho Dec 05 '19 at 14:29
  • @bialy The weird thing is that if I comment all the code that is in the slot of the AI thread the problem doesn't happen. And I have also measured the time it takes to run the slot and it is insignificant. At the moment I have disconnected the Control thread to try figure out what is happening – Leonardo Costa Dec 05 '19 at 14:31
  • @vahancho It is running in debug mode – Leonardo Costa Dec 05 '19 at 14:33
  • @LeonardoCosta, hm, but maybe that's the reason of why it takes 5ms? What if you try the optimized build and compare the timings? – vahancho Dec 05 '19 at 14:37
  • @LeonardoCosta, in general, you should not rely on the performance measurements made with debug builds. You should do it with optimized builds only to get reasonable results. – vahancho Dec 05 '19 at 14:55
  • @vahancho To run a optimized build do I have to manually configure how Qt builds my application or just by running the application without debugging is enough ? If I run it without debugging I get the same result – Leonardo Costa Dec 05 '19 at 14:59
  • QueuedConnection is a necessity for the UI thread slots, because only the UI thread is allowed to update its user interface objects. But the connections between the other threads could be [DirectConnection](https://doc.qt.io/qt-5/qt.html#ConnectionType-enum), unless there is other restriction. – Former contributor Dec 05 '19 at 15:04
  • @LeonardoCosta, can you build your application in release mode? If yes, build it and run to measure the time. It's not the same as running a debug build without debugging. – vahancho Dec 05 '19 at 15:05
  • @vahancho running it in release mode fixed it – Leonardo Costa Dec 05 '19 at 15:19
  • 1
    @LeonardoCosta, it's not a fix, but rather how it works. Debug builds are always slower:) – vahancho Dec 05 '19 at 15:33
  • 1
    I found out what was causing the delay. Recently I've been doing some re-organization of the code, and in the older version there mutexes in a lot of parts of the code to protect some variables and there was a mutex in the copy constructor of my ClassData, which is used by Qt when sending the signal. What was happening is that the delay that `emit signal...` caused was due to the time it had to wait to get the lock on the mutex. By readjusting the mutexes the delay was gone even when running in debug mode. – Leonardo Costa Dec 05 '19 at 17:04

0 Answers0