Solved Make QNetworkAccessManager threadsafe
-
@Phoenox said in Make QNetworkAccessManager threadsafe:
Question 1: Is this correct?
Yes, that's correct. NAM uses threading internally though.
Question 2: Is this feasible?
It's a good plan. However you can just use plain ol' signal and slots instead of using your own thread-safe wrapper around the (single) NAM instance.
@Buckwheat said in Make QNetworkAccessManager threadsafe:
Typically "re-entrant" implies thread-safe as variables are on the stack and do not interfere with each other.
Not exactly. Reentrant literally means a thread can be interrupted and then the reentry can be made without side effects. This implies that the variables are thread-local (independent of stack or heap), i.e. there are no globals to take care of.
-
@kshegunov ... correct. but add... there are no side-effects if invoked again before the last invocation finishes. Hence no static (global) members. The safest way is still to use mutexing and protect yourself.
-
@Buckwheat said in Make QNetworkAccessManager threadsafe:
... correct. but add...
No "but". It means safe for re-entry. It doesn't include "if invoked again". A global may be modified from anywhere, and a thread context switch can happen (almost) anywhere, so there's no reason to think that there's need for a condition to be put to the function to be called a second time.
-
@kshegunov ...
https://en.wikipedia.org/wiki/Reentrancy_(computing)
Reentrancy (computing) In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution, and then be safely called again ("re-entered") before its previous invocations complete execution.
That is the definition I grew up in computing when concurrency was a nifty trick and threads were not part of the OS. So, both are correct. I had already mentioned the exception of globals. So, no need to be angry and snotty.
-
So, no need to be angry and snotty.
Not intended as such, sorry if it was perceived this way. I meant the following (real code):
int testFunction() { int x = 0; return x + 5; }
leading to:
11 [1] { 0x5555555568f0 55 push %rbp 0x5555555568f1 <+0x0001> 48 89 e5 mov %rsp,%rbp 12 [1] int x = 0; 0x5555555568f4 <+0x0004> c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) 13 [1] return x + 5; 0x5555555568fb <+0x000b> 8b 45 fc mov -0x4(%rbp),%eax 0x5555555568fe <+0x000e> 83 c0 05 add $0x5,%eax 14 [1] } 0x555555556901 <+0x0011> 5d pop %rbp 0x555555556902 <+0x0012> c3 retq
This function can be thought reentrant if a thread breaks after the
movl $0x0,-0x4(%rbp)
and when re-entering it can executemov -0x4(%rbp),%eax
without side effects, which is the implication that another thread can't (or will not) modify-0x4(%rbp)
while the former is sleeping. And since one can't control where context switches are done, we get the implication that globals break reentrancy. So that's what I meant by It doesn't include "if invoked again".Kind regards.
-
@kshegunov ... I said globals are bad: "That being said, if there are static methods being called using static members than that can cause problems." I hate to date myself, but I was writing machine guidance and avionics before you were actually born! LOL!
-
@Buckwheat said in Make QNetworkAccessManager threadsafe:
I said globals are bad
Never claimed you hadn't. I was just expanding on my comment, making it clearer what I meant, or at least I hope.
-
@kshegunov ... I said globals are bad: "That being said, if there are static methods being called using static members than that can cause problems."
One more thing. Your example is always re-entrant and always thread-safe no matter what circumstances because it is all stack/frame pointer based. So it proves the point I was making. Only in languages like FORTRAN where all variables are static would there be a problem. But you can also make some really cool design strategies with it.
-
@kshegunov ... OK. It is hard to have tech discussions like this. A large cup of coffee and a nice Xtreme session would be ideal :D
-
Okay, I just protected my single instance of the QNetworkAccessManager with mutexes, as @Buckwheat suggested.
Until now, I'm not experiencing any problems.Thanks everyone for the tips and the clarification on reentrancy/thread-safety.