qInstallMessageHandler successful, but sub thread can't see it - c++

I have an app written with Qt5. There is a parent process which spins off an array of child threads - works fine. When I was prototyping it I installed my own message handler (with qInstallMessageHandler) to customize logging, but I put the call to install the message handler in each thread that was spun off (effectively the threads are little clones of each other, so every thread created had the call to install the message handler). Oddly enough that worked. Even though qInstallMessageHandler should only be called once for an application (only one can have the ring of power), calling it multiple times evidently worked because they were all for the same handler. All the threads sent their qDebug (qWarning, etc) messages to my handler and so did the parent.
Now that I'm finalizing the prototype, I wanted to clean things up so I moved the call for qInstallMessageHandler into the parent (which seems cleaner), but now only the parent uses the message handler but the child threads seem to be oblivious that it is installed. I can't see why this doesn't work. The QMessageHandler is application scope. The actual message handler code is outside of any class (as it's always been).
Can anyone offer any insight as to why the threads can't see my handler?

So here's the deal. My parent process is a daemon (QtService) which it turns out was trying to install a message handler of its own (because I defined debugging for it). When I called the message handler from within my thread the timing was such that I stole the handler from qservice, but when I moved it into the daemon proper, qservice stole the handler from me. In any case, I was just stepping on my own toes as usual. Whoever calls qInstallMessageHandler last wins.

Related

Cross thread call a.k.a run on main/UI thread from other thread without dependencies needed

I'm on some c++ mobile product, but I need my apps main thread is still running without any blocking when doing some heavy work on the background thread and run back on main thread. But I realized there is no runOnMainThread/runOnUIThread in c++ thread api. I trying to figure it out the issue and found that need to depend library, or create your own thread event queue. Although it is good, but i am thinking to have a behavior which can runOnUIThread.
How it does not work: the mentioned library creates a timer, installs a SIGALRM signal handler and dispatches queued tasks when signals are fired. This allows tasks being processed on the main thread even when it is busy. However POSIX permits only a small set of async-signal-safe functions to be invoked inside of signal handler. Running arbitrary с++ code inside of signal handler violates that restriction and leaves application in hopelessly doomed state.
After some research and development, I've created a library called NonBlockpp
it is a small c++ library to allow c++ mobile application able to process the heavy and time consuming task on background and back to Main thread again, It’s been tested and fired the main thread event.
It also allow to save the tasks and fire them later, all the task has no blocking each other and thread safety.
How it works:
If you found any query or suggestion, please don't hesitate to raise an issue and we can discuss it together.
The project has rectify from signal to pollEvent due to signal handler might not be safe to use.
Please take a look the new changed.
NonBlockpp
Usage

Qt: The relation between Worker thread and GUI Events

I have an ordinary GUI Thread (Main Window) and want to attach a Worker thread to it. The Worker thread will be instantiated, moved to its own thread and then fired away to run on its own independently, running a messaging routine (non-blocking).
This is where the worker is created:
void MainWindow::on_connectButton_clicked()
{
Worker* workwork;
workwork= new Worker();
connect(workwork,SIGNAL(invokeTestResultsUpdate(int,quint8)),
this,SLOT(updateTestResults(int,quint8)),Qt::QueuedConnection);
connect(this,SIGNAL(emitInit()),workwork,SLOT(init()));
workwork->startBC();
}
This is where the Worker starts:
void Worker::startBC()
{
t1553 = new QThread();
this->moveToThread(t1553);
connect(t1553,SIGNAL(started()),this,SLOT(run1553Process()));
t1553->start();
}
I have two problems here, regarding the event queue of the new thread:
The first and minor problem is that, while I can receive the signals from the Worker thread (namely: invokeTestResultsUpdate), I cannot invoke the init method by emitting the emitInit signal from MainWindow. It just doesn't fire unless I call it directly or connect it via Qt::DirectConnection . Why is this happening? Because I have to start the Worker thread's own messaging loop explicitly? Or some other thing I'm not aware of? (I really fail to wrap my head around the concept of Thread/Event Loop/Signal Slot mechanism and the relation between each other even though I try. I welcome any fresh perspective here too.)
The second and more obscure problem is: run1553process method does some heavy work. By heavy work, I mean a very high rate of data. There is a loop running, and I try to receive the data flowing from a device (real-time) as soon as it lands in the buffer, using mostly extern API functions. Then throw the mentioned invokeTestResultsUpdate signal towards the GUI each time it receives a message, updating the message number box. It's nothing more than that.
The thing I'm experiencing is weird; normally the messaging routine is mostly unhindered but when I resize the main window, move it, or hide/show the window, the Worker thread skips many messages. And the resizing action is really slow (not responds very fast). It's really giving me a cancer.
(Note: I have tried subclassing QThread before, it did not mitigate the problem.)
I've been reading all the "Thread Affinity" topics and tried to apply them but it still behaves like it is somehow interrupted by the GUI thread's events at some point. I can understand MainWindow's troubles since there are many messages at the queue to be executed (both the invoked slots and the GUI events). But I cannot see as to why a background thread is affected by the GUI events. I really need to have an extremely robust and unhindered message routine running seperately behind, firing and forgetting the signals and not giving a damn about anything.
I'm really desperate for any help right now, so any bit of information is useful for me. Please do not hesitate to throw ideas.
TL;DR: call QCoreApplication::processEvents(); periodiacally inside run1553process.
Full explanation:
Signals from the main thread are put in a queue and executed once the event loop in the second thread takes control. In your implementation you call run1553Process as soon as the thread starts. the control will not go back to the event loop until the end of that function or QCoreApplication::processEvents is manually invoked so signals will just sit there waiting for the event loop to pick them up.
P.S.
you are leaking both the worker and the thread in the code above
P.P.S.
Data streams from devices normally provide an asynchronous API instead of you having to poll them indefinetly
I finally found the problem.
The crucial mistake was connecting the QThread's built in start() signal to run1553Process() slot. I had thought of this as replacing run() with this method, and expected everything to be fine. But this caused the actual run() method to get blocked, therefore preventing the event loop to start.
As stated in qthread.cpp:
void QThread::run()
{
(void) exec();
}
To fix this, I didn't touch the original start() signal, instead connected another signal to my run1553Process() independently. First started the thread ordinarily, allowed the event loop to start, then fired my other signals. That did it, now my Worker can receive all the messages.
I think now I understand the relation between threads and events better.
By the way, this solution did not take care of the message skipping problem entirely, but I feel that's caused by another factor (like my message reading implementation).
Thanks everyone for the ideas. I hope the solution helps some other poor guy like me.

need help in UI threads in C++

I'm using UI threads and I built one thread with message map and it works fine, the problem is when I'm tring to create another thread from the first one.
When I'm getting to this line:
this->PostThreadMessage(WM_MYTHREADMESSAGE,0,0);
I'm getting the next message:
"No symbols are loaded for any call stack frame. The source code cannot be displayed"
I dont know if its could be the reason for the problem but I have built two message maps, one for each thread, I don't know if its ok to do so.
The question is difficult to understand. I'm assuming that you're stepping through your program in the debugger, and you get to that PostThreadMessage line.
If you choose Step Into, the debugger will try to step into the PostThreadMessage call (or the framework wrapper, depending on the type of this). Since PostThreadMessage is a system call, it's likely you don't have symbols for that code. The debugger will just show you disassembly. You can try to use the Microsoft symbol server, but I don't see much point in trying to trace into PostThreadMessage. If the parameters are right, it's going to post the message to the specified thread's queue. Not much to see there.
Posting message to other threads is tricky business. Most Windows programs, even multithreaded ones, typically keep all the UI work to a single thread. It can be done, but there are a lot of caveats and it's usually not worth the pain.
So there are couple of things:
if you want to notify the UI thread from the worker thread, then you should not use PostThreadMessage, here is why.
When this->PostThreadMessage(...) called in a member function of thread A, the message will be sent to thread A, because this points to CWinThread of A. You have to get a pointer to the other thread to post a message to it.
Finally if you want to notify your UI thread, use PostMessage to send a message to the window created by that thread. Add a corresponding handler to the window message map.
Hope this helps

what can I use to replace sleep and usleep in my Qt app?

I'm importing a portion of existing code into my Qt app and noticed a sleep function in there. I see that this type of function has no place in event programming. What should I do instead?
UPDATE: After thought and feedback I would say the answer is: call sleep outside the GUI main thread only and if you need to wait in the GUI thread use processEvents() or an event loop, this will prevent the GUI from freezing.
It isn't pretty but I found this in the Qt mailing list archives:
The sleep method of QThread is protected, but you can expose it like so:
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
Then just call:
SleeperThread::msleep(1000);
from any thread.
However, a more elegant solution would be to refactor your code to use a QTimer - this might require you saving the state so you know what to do when the timer goes off.
I don't recommend sleep in a event based system but if you want to ...
You can use a waitcondition, that way you can always interrupt the sleep if neccesary.
//...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
The reason why sleep is a bad idea in event based programming is because event based programming is effectively a form on non-preemptive multitasking. By calling sleep, you prevent any other event becoming active and therefore blocking the processing of the thread.
In a request response scenario for udp packets, send the request and immediately wait for the response. Qt has good socket APIs which will ensure that the socket does not block while waiting for the event. The event will come when it comes. In your case the QSocket::readReady signal is your friend.
If you want to schedule an event for some point of time in the future, use QTimer. This will ensure that other events are not blocked.
It is not necessary to break down the events at all. All I needed to do was to call QApplication::processEvents() where sleep() was and this prevents the GUI from freezing.
I don't know how the QTs handle the events internally, but on most systems at the lowest level the application life goes like this: the main thread code is basically a loop (the message loop), in which, at each iteration, the application calls a function that gives to it a new message; usually that function is blocking, i.e. if there are no messages the function does not return and the application is stopped.
Each time the function returns, the application has a new message to process, that usually has some recipient (the window to which is sent), a meaning (the message code, e.g. the mouse pointer has been moved) and some additional data (e.g. the mouse has been moved to coords 24, 12).
Now, the application has to process the message; the OS or the GUI toolkit usually do this under the hood, so with some black magic the message is dispatched to its recipient and the correct event handler is executed. When the event handler returns, the internal function that called the event handler returns, so does the one that called it and so on, until the control comes back to the main loop, that now will call again the magic message-retrieving function to get another message. This cycle goes on until the application terminates.
Now, I wrote all this to make you understand why sleep is bad in an event driven GUI application: if you notice, while a message is processed no other messages can be processed, since the main thread is busy running your event handler, that, after all, is just a function called by the message loop. So, if you make your event handler sleep, also the message loop will sleep, which means that the application in the meantime won't receive and process any other messages, including the ones that make your window repaint, so your application will look "hang" from the user perspective.
Long story short: don't use sleep unless you have to sleep for very short times (few hundreds milliseconds at most), otherwise the GUI will become unresponsive. You have several options to replace the sleeps: you can use a timer (QTimer), but it may require you to do a lot of bookkeeping between a timer event and the other. A popular alternative is to start a separate worker thread: it would just handle the UDP communication, and, being separate from the main thread, it would not cause any problem sleeping when necessary. Obviously you must take care to protect the data shared between the threads with mutexes and be careful to avoid race conditions and all the other kind of problems that occur with multithreading.

Crash with boost::thread

I am using wxwidgets together with boost::thread. The Thread is a worker thread which sends some Events to the GUI:
Thread creation:
thrd = boost::thread(boost::bind(workerFunction,this));
Send Message to the GUI:
wxPostEvent(loWindow, event);
wxSafeYield();
Under Windows I don't see any problems, but when starting the application under Linux (Ubuntu 8.10), it stops with the following error message:
_XCBUnlockDisplay: Assertion `xcb_get_request_sent(dpy->xcb->connection) == dpy->request' failed.
Aborted
What am I missing? When the workerFunction is not started in a thread, it works without problems.
Regards,
/mspoerr
Don't call wxYield from a worker thread. Only do that from the GUI thread. Yield will process gui events, and is intended to be used if in some GUI event handler you do much of work and want to update other controls and process pending events in between. The Safe in wxSafeYield means that it disables GUI controls before it processes pending events first. That will protect you from such cases like entering the event handler you called wxYield from a second time, recursively. It doesn't mean that it is thread-safe, or something like that.
If you want to give the rest of the time slice your thread would have to other threads, call wx's wxThread::Yield or boost's this_thread::yield (depending on your thread class) instead.
The problem was with the data I sent - for complex data you need to use custom events. I now implemented a custom event and it works.
For more information please see http://forums.wxwidgets.org/viewtopic.php?t=24663
Thank you for your help!
/mspoerr
EDIT: Updated the link. The old one was broken