Solved Make QNetworkAccessManager threadsafe
-
@Phoenox ...
Typically "re-entrant" implies thread-safe as variables are on the stack and do not interfere with each other. That being said, if there are static methods being called using static members than that can cause problems.If you are worried, use your own mutexes around your access points into QNetworkAccessManager then you make your own thread-safety for that instance.
-
@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.