Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Make QNetworkAccessManager threadsafe

Make QNetworkAccessManager threadsafe

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 4.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • PhoenoxP Offline
    PhoenoxP Offline
    Phoenox
    wrote on last edited by
    #1

    Hello everyone,

    in my application, I'm using a QNetworkAccessManager (cached and with a QNetworkCookieJar).
    The documentation mentions that QNetworkAccessManager is just reentrant, not threadsafe.
    This SO post also says that if using multiple threads, one should use one instance per thread.

    Question 1: Is this correct? It seems a bit counter-intuitive that I have to create multiple instances of a QNetworkAccessManager for multi-threaded applications, although the documentation also mentions that "One QNetworkAccessManager should be enough for the whole Qt application."

    If the QNetworkAccessManager is indeed just reentrant, my plan is to work around this limitation by running just one QNetworkAccessManager in a dedicated thread, which is managed by a threadsafe object. Requests would then only be sent through this threadsafe object.

    Question 2: Is this feasible? Is there an easier solution? My only requirements are that I want to have only one instance of the QNetworkAccessManager and still use it from different threads.

    Cheers
    PhoeNox

    kshegunovK 1 Reply Last reply
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      Hi,
      maybe you should keep a one and only net work manager in the main thread and do the work initiated by the requests it gets in separate threads.
      -Michael.

      1 Reply Last reply
      0
      • BuckwheatB Offline
        BuckwheatB Offline
        Buckwheat
        wrote on last edited by
        #3

        @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.

        Dave Fileccia

        1 Reply Last reply
        1
        • PhoenoxP Phoenox

          Hello everyone,

          in my application, I'm using a QNetworkAccessManager (cached and with a QNetworkCookieJar).
          The documentation mentions that QNetworkAccessManager is just reentrant, not threadsafe.
          This SO post also says that if using multiple threads, one should use one instance per thread.

          Question 1: Is this correct? It seems a bit counter-intuitive that I have to create multiple instances of a QNetworkAccessManager for multi-threaded applications, although the documentation also mentions that "One QNetworkAccessManager should be enough for the whole Qt application."

          If the QNetworkAccessManager is indeed just reentrant, my plan is to work around this limitation by running just one QNetworkAccessManager in a dedicated thread, which is managed by a threadsafe object. Requests would then only be sent through this threadsafe object.

          Question 2: Is this feasible? Is there an easier solution? My only requirements are that I want to have only one instance of the QNetworkAccessManager and still use it from different threads.

          Cheers
          PhoeNox

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @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.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          3
          • BuckwheatB Offline
            BuckwheatB Offline
            Buckwheat
            wrote on last edited by
            #5

            @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.

            Dave Fileccia

            kshegunovK 1 Reply Last reply
            0
            • BuckwheatB Buckwheat

              @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.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @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.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • BuckwheatB Offline
                BuckwheatB Offline
                Buckwheat
                wrote on last edited by
                #7

                @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.

                Dave Fileccia

                kshegunovK 1 Reply Last reply
                0
                • BuckwheatB Buckwheat

                  @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.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #8

                  @Buckwheat

                  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 execute mov -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.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  0
                  • BuckwheatB Offline
                    BuckwheatB Offline
                    Buckwheat
                    wrote on last edited by
                    #9

                    @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!

                    Dave Fileccia

                    kshegunovK BuckwheatB 2 Replies Last reply
                    0
                    • BuckwheatB Buckwheat

                      @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!

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #10

                      @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.

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      0
                      • BuckwheatB Buckwheat

                        @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!

                        BuckwheatB Offline
                        BuckwheatB Offline
                        Buckwheat
                        wrote on last edited by
                        #11

                        @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.

                        Dave Fileccia

                        1 Reply Last reply
                        0
                        • BuckwheatB Offline
                          BuckwheatB Offline
                          Buckwheat
                          wrote on last edited by
                          #12

                          @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

                          Dave Fileccia

                          1 Reply Last reply
                          1
                          • PhoenoxP Offline
                            PhoenoxP Offline
                            Phoenox
                            wrote on last edited by
                            #13

                            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.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved