Function not always returning if called in thread???
-
Just now wasted(!) about 3 hours to resolve some undefined error, which was odd, because i was sure i do everything right(and i still think i did). After that, there is only two answers:
- it is some C++/Qt/QThread bug (which i'm doubt).
- i don't know some essential mechanics of C++ or QThreads.
If you order to use some ordinary function, you expecting that program will not go forward until that function is finish and gives the return? Right?
code code code... bool func1(); int func2(); ...
Well, in my case, after i called
func1
- program did'nt wait it's finish+return(as it suppose to), instead, it keeps runinng next lines, func2 etc. In the result - runtime crash, which source was hard to define.My funcion(void reportToConsole(QString)), is declared in header file, as global or static result is the same. It uses only input params as QString, and pointer to object(see screenshoot below). That function runs like in 40 different places in my files, but crashes only in one place - loop function, started by MainWorker. After that function - scope ends(of if-else), and because function can not finish - scope ends, and it ceased to exist, or i dont know what else happened here. So i artificially adding some time to it so it can finish it's own execution...:
So it is silly, sleep after, gives it necessary time to finish itself. Then i tried same but inside function itself:
Works as well. But i can't do that because that might slow the app. And sometimes 10msec or 50 is not enough, and it crashes, sometimes long work with 10msec and everything fine.
I thought, maybe that happens because it calls function too frequently, and QTextBrowser can not comprehend appends such fast, tried two functions in a row in some MainWindow function:
void reportToConsole("text1"); void reportToConsole("text2");
but of course it's not QTextBrowser, everything calls and returns properly and appends immediately so it's definitely QThread.
So can anybody, please, clarify me, what is going on with that function and why it all works such wrong like C++ is broken?
P.S. after i added that function, in runtime it started to get some strange application output:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)Also strange, because why would qt ask register it's own metatype. After i added
qRegisterMetaType<QTextCursor>("QTextCursor");
runtime message gone, but i thought it might be one of the reason of my crashes. -
@Engelard said in Function not always returning if called in thread???:
If you order to use some ordinary function, you expecting that program will not go forward until that function is finish and gives the return? Right?
code code code... bool func1(); int func2(); ...
Right. That is guaranteed in C++.
Well, in my case, after i called
func1
- program did'nt wait it's finish+return(as it suppose to), instead, it keeps runinng next lines, func2 etc.I assure you that your code does wait for func1() to return. Your program crashes because your code contains 2 problems:
- Your code has race conditions. You must protect data/objects that are accessed by multiple threads: https://en.wikipedia.org/wiki/Race_condition#Software
- As @SGaist said, you cannot call
QTextBrowser
functionsfrom another thread. A GUI-related classes in Qt can only be accessed from the GUI thread. (The GUI thread is the thread that createsQGuiApplication
/QApplication
)
Just now wasted(!) about 3 hours to resolve some undefined error
It's not wasted if you learnt something new. After those 3 hours, you now know how to handle similar errors in the future much faster, right?
-
Hi,
From the looks of your code, you are trying to modify widgets from a different thread than the GUI thread which is forbidden. You can use signal and slots to transfert your text from your threads back to the GUI thread and append the text there.
-
@SGaist said in Function not always returning if called in thread???:
You can use signal and slots to transfert your text from your threads back to the GUI thread and append the text there.
I thought about Sig&Slots from the very beginning, there is no way i can use them for such a function, since it should be simple to call, from any place of my code, for any .cpp.
And there is no global/static
SIGNALs
in Qt. If it were, it would be damn simple, sure) -
@SGaist is right, the function being called will "live/execute" inside the calling thread.
So, as a result, you try to access a Gui element the QTextBrowser from a non Gui thread.Which is probably the cause for your problems.
And there is no global/static SIGNALs in Qt. If it were, it would be damn simple, sure)
Well, I hate to be the guy to suggest this. But you could create a singleton(QObject-based ) class, that would make it "global"
-
@Engelard said in Function not always returning if called in thread???:
If you order to use some ordinary function, you expecting that program will not go forward until that function is finish and gives the return? Right?
code code code... bool func1(); int func2(); ...
Right. That is guaranteed in C++.
Well, in my case, after i called
func1
- program did'nt wait it's finish+return(as it suppose to), instead, it keeps runinng next lines, func2 etc.I assure you that your code does wait for func1() to return. Your program crashes because your code contains 2 problems:
- Your code has race conditions. You must protect data/objects that are accessed by multiple threads: https://en.wikipedia.org/wiki/Race_condition#Software
- As @SGaist said, you cannot call
QTextBrowser
functionsfrom another thread. A GUI-related classes in Qt can only be accessed from the GUI thread. (The GUI thread is the thread that createsQGuiApplication
/QApplication
)
Just now wasted(!) about 3 hours to resolve some undefined error
It's not wasted if you learnt something new. After those 3 hours, you now know how to handle similar errors in the future much faster, right?
-
@JKSH said in Function not always returning if called in thread???:
Your code has race conditions. You must protect data/objects that are accessed by multiple threads: https://en.wikipedia.org/wiki/Race_condition#Software
Hey, that's very informative link! Thats fully explains what happening during execution of my func. Thanks.
It's good to know again, that Earth spinning around the Sun, gravity pulls things down and programs does'nt run forward until they finish execution of the function.Result:
At the first i invented some upgrade, added second (predefined)parameter:
static void reportToConsole(QString msg, int pause=0) { tBrowPtr->append("<font color=\"#808080\">"+currentTime()+ ":</font color>"+msg); if(pause!=0) Sleep(pause); }
I could specify some amout of mSecs to wait, if func used in my Thread loop.
Works well, but then i read that stuff @JKSH posted, and realized that even specifying 20 or even 30 msecs - not guaranteeing safe execution. App simply could be running at old slow PC, and those mSecs amount might not be enough.
So i creating simple "another" function which connects MainWindow and Worker, so error send from the worker will be executed in MainWindow SLOT. Like in old days...
Now the only tiny thing left - how can i forbid Workers thread use my global common function instead of emiting Signal. Could accidentally, call wrong reportToConsole)