why concurrentQueue.sync DON'T cause deadlock



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















This code will deadlock because:



  1. they are in same thread

  2. print(2) has to wait print(3)

  3. print(3) has to wait print(2)

For example:



DispatchQueue.main.async 
print(Thread.current)
DispatchQueue.main.sync
print(Thread.current)
print(2)

print(3)



Why in the concurrentQueue won't cause deadlock? They are also in same thread.



DispatchQueue.global().async 
print(Thread.current)
DispatchQueue.global().sync
print(Thread.current)
print(2)

print(3)










share|improve this question






























    1















    This code will deadlock because:



    1. they are in same thread

    2. print(2) has to wait print(3)

    3. print(3) has to wait print(2)

    For example:



    DispatchQueue.main.async 
    print(Thread.current)
    DispatchQueue.main.sync
    print(Thread.current)
    print(2)

    print(3)



    Why in the concurrentQueue won't cause deadlock? They are also in same thread.



    DispatchQueue.global().async 
    print(Thread.current)
    DispatchQueue.global().sync
    print(Thread.current)
    print(2)

    print(3)










    share|improve this question


























      1












      1








      1








      This code will deadlock because:



      1. they are in same thread

      2. print(2) has to wait print(3)

      3. print(3) has to wait print(2)

      For example:



      DispatchQueue.main.async 
      print(Thread.current)
      DispatchQueue.main.sync
      print(Thread.current)
      print(2)

      print(3)



      Why in the concurrentQueue won't cause deadlock? They are also in same thread.



      DispatchQueue.global().async 
      print(Thread.current)
      DispatchQueue.global().sync
      print(Thread.current)
      print(2)

      print(3)










      share|improve this question
















      This code will deadlock because:



      1. they are in same thread

      2. print(2) has to wait print(3)

      3. print(3) has to wait print(2)

      For example:



      DispatchQueue.main.async 
      print(Thread.current)
      DispatchQueue.main.sync
      print(Thread.current)
      print(2)

      print(3)



      Why in the concurrentQueue won't cause deadlock? They are also in same thread.



      DispatchQueue.global().async 
      print(Thread.current)
      DispatchQueue.global().sync
      print(Thread.current)
      print(2)

      print(3)







      ios concurrency grand-central-dispatch deadlock






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 22 '18 at 2:15









      Rob

      307k51580751




      307k51580751










      asked Nov 14 '18 at 5:56









      pangyuleipangyulei

      66




      66






















          1 Answer
          1






          active

          oldest

          votes


















          0














          You ask:




          Why in the concurrentQueue won't cause deadlock? They are also in same thread.




          No, they're necessarily in the same thread. They're in the same queue, but not necessarily the same thread. (As part of an optimization, see below, it actually might end up running on the same thread, but not necessarily so. But logically, you should think of it as running on a separate thread.)



          This is the whole idea behind "concurrent queues" is that they can run individual dispatched tasks on different threads. That's how they permit concurrent operation. One dispatched task on concurrent queue can run on one thread while another dispatched task on that same queue can run on a separate thread.



          As the old Concurrency Programming Guide says in its definition of a "concurrent queue":




          The currently executing tasks run on distinct threads that are managed by the dispatch queue.




          Or, as the DispatchQueue documentation says:




          DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system. [emphasis added]





          What makes this a little more confusing is that there is a GCD optimization that, if you are dispatching synchronously ...




          As a performance optimization, this function executes blocks on the current thread whenever possible...




          So, when dispatching synchronously from a queue, it actually can end up running that code on the same thread (unless you’re dispatching from a background queue to the main queue). Consider:



          let queue = DispatchQueue.global()
          let queue2 = DispatchQueue(label: "queue2")

          queue.async
          print(1, Thread.current)
          queue2.sync
          print(2, Thread.current)

          print(3, Thread.current)



          That second print statement will show that even though you have a completely different queue, it may, as part of the aforementioned sync optimization, run the code on the current thread. The same it true if that inner sync call was to the same queue to which the outer block was dispatched.



          Now, when looking at the result of this optimization, it feels like this is just like the serial queue scenario, but it’s not. A serial queue only allows one dispatched task to run at a time, and thus the attempt to dispatch synchronously (blocking the current thread until the dispatched block runs) to itself is, by definition, a deadlock.



          But the concurrent queue dispatching to itself is not a deadlock, even though, because of this sync optimization, it may end up running the code on the same thread.






          share|improve this answer

























          • but I print [NSThread currentThread] it's same thread.

            – pangyulei
            Apr 8 at 13:52











          • Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

            – Rob
            Apr 8 at 16:29











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53293965%2fwhy-concurrentqueue-sync-dont-cause-deadlock%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          You ask:




          Why in the concurrentQueue won't cause deadlock? They are also in same thread.




          No, they're necessarily in the same thread. They're in the same queue, but not necessarily the same thread. (As part of an optimization, see below, it actually might end up running on the same thread, but not necessarily so. But logically, you should think of it as running on a separate thread.)



          This is the whole idea behind "concurrent queues" is that they can run individual dispatched tasks on different threads. That's how they permit concurrent operation. One dispatched task on concurrent queue can run on one thread while another dispatched task on that same queue can run on a separate thread.



          As the old Concurrency Programming Guide says in its definition of a "concurrent queue":




          The currently executing tasks run on distinct threads that are managed by the dispatch queue.




          Or, as the DispatchQueue documentation says:




          DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system. [emphasis added]





          What makes this a little more confusing is that there is a GCD optimization that, if you are dispatching synchronously ...




          As a performance optimization, this function executes blocks on the current thread whenever possible...




          So, when dispatching synchronously from a queue, it actually can end up running that code on the same thread (unless you’re dispatching from a background queue to the main queue). Consider:



          let queue = DispatchQueue.global()
          let queue2 = DispatchQueue(label: "queue2")

          queue.async
          print(1, Thread.current)
          queue2.sync
          print(2, Thread.current)

          print(3, Thread.current)



          That second print statement will show that even though you have a completely different queue, it may, as part of the aforementioned sync optimization, run the code on the current thread. The same it true if that inner sync call was to the same queue to which the outer block was dispatched.



          Now, when looking at the result of this optimization, it feels like this is just like the serial queue scenario, but it’s not. A serial queue only allows one dispatched task to run at a time, and thus the attempt to dispatch synchronously (blocking the current thread until the dispatched block runs) to itself is, by definition, a deadlock.



          But the concurrent queue dispatching to itself is not a deadlock, even though, because of this sync optimization, it may end up running the code on the same thread.






          share|improve this answer

























          • but I print [NSThread currentThread] it's same thread.

            – pangyulei
            Apr 8 at 13:52











          • Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

            – Rob
            Apr 8 at 16:29















          0














          You ask:




          Why in the concurrentQueue won't cause deadlock? They are also in same thread.




          No, they're necessarily in the same thread. They're in the same queue, but not necessarily the same thread. (As part of an optimization, see below, it actually might end up running on the same thread, but not necessarily so. But logically, you should think of it as running on a separate thread.)



          This is the whole idea behind "concurrent queues" is that they can run individual dispatched tasks on different threads. That's how they permit concurrent operation. One dispatched task on concurrent queue can run on one thread while another dispatched task on that same queue can run on a separate thread.



          As the old Concurrency Programming Guide says in its definition of a "concurrent queue":




          The currently executing tasks run on distinct threads that are managed by the dispatch queue.




          Or, as the DispatchQueue documentation says:




          DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system. [emphasis added]





          What makes this a little more confusing is that there is a GCD optimization that, if you are dispatching synchronously ...




          As a performance optimization, this function executes blocks on the current thread whenever possible...




          So, when dispatching synchronously from a queue, it actually can end up running that code on the same thread (unless you’re dispatching from a background queue to the main queue). Consider:



          let queue = DispatchQueue.global()
          let queue2 = DispatchQueue(label: "queue2")

          queue.async
          print(1, Thread.current)
          queue2.sync
          print(2, Thread.current)

          print(3, Thread.current)



          That second print statement will show that even though you have a completely different queue, it may, as part of the aforementioned sync optimization, run the code on the current thread. The same it true if that inner sync call was to the same queue to which the outer block was dispatched.



          Now, when looking at the result of this optimization, it feels like this is just like the serial queue scenario, but it’s not. A serial queue only allows one dispatched task to run at a time, and thus the attempt to dispatch synchronously (blocking the current thread until the dispatched block runs) to itself is, by definition, a deadlock.



          But the concurrent queue dispatching to itself is not a deadlock, even though, because of this sync optimization, it may end up running the code on the same thread.






          share|improve this answer

























          • but I print [NSThread currentThread] it's same thread.

            – pangyulei
            Apr 8 at 13:52











          • Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

            – Rob
            Apr 8 at 16:29













          0












          0








          0







          You ask:




          Why in the concurrentQueue won't cause deadlock? They are also in same thread.




          No, they're necessarily in the same thread. They're in the same queue, but not necessarily the same thread. (As part of an optimization, see below, it actually might end up running on the same thread, but not necessarily so. But logically, you should think of it as running on a separate thread.)



          This is the whole idea behind "concurrent queues" is that they can run individual dispatched tasks on different threads. That's how they permit concurrent operation. One dispatched task on concurrent queue can run on one thread while another dispatched task on that same queue can run on a separate thread.



          As the old Concurrency Programming Guide says in its definition of a "concurrent queue":




          The currently executing tasks run on distinct threads that are managed by the dispatch queue.




          Or, as the DispatchQueue documentation says:




          DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system. [emphasis added]





          What makes this a little more confusing is that there is a GCD optimization that, if you are dispatching synchronously ...




          As a performance optimization, this function executes blocks on the current thread whenever possible...




          So, when dispatching synchronously from a queue, it actually can end up running that code on the same thread (unless you’re dispatching from a background queue to the main queue). Consider:



          let queue = DispatchQueue.global()
          let queue2 = DispatchQueue(label: "queue2")

          queue.async
          print(1, Thread.current)
          queue2.sync
          print(2, Thread.current)

          print(3, Thread.current)



          That second print statement will show that even though you have a completely different queue, it may, as part of the aforementioned sync optimization, run the code on the current thread. The same it true if that inner sync call was to the same queue to which the outer block was dispatched.



          Now, when looking at the result of this optimization, it feels like this is just like the serial queue scenario, but it’s not. A serial queue only allows one dispatched task to run at a time, and thus the attempt to dispatch synchronously (blocking the current thread until the dispatched block runs) to itself is, by definition, a deadlock.



          But the concurrent queue dispatching to itself is not a deadlock, even though, because of this sync optimization, it may end up running the code on the same thread.






          share|improve this answer















          You ask:




          Why in the concurrentQueue won't cause deadlock? They are also in same thread.




          No, they're necessarily in the same thread. They're in the same queue, but not necessarily the same thread. (As part of an optimization, see below, it actually might end up running on the same thread, but not necessarily so. But logically, you should think of it as running on a separate thread.)



          This is the whole idea behind "concurrent queues" is that they can run individual dispatched tasks on different threads. That's how they permit concurrent operation. One dispatched task on concurrent queue can run on one thread while another dispatched task on that same queue can run on a separate thread.



          As the old Concurrency Programming Guide says in its definition of a "concurrent queue":




          The currently executing tasks run on distinct threads that are managed by the dispatch queue.




          Or, as the DispatchQueue documentation says:




          DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system. [emphasis added]





          What makes this a little more confusing is that there is a GCD optimization that, if you are dispatching synchronously ...




          As a performance optimization, this function executes blocks on the current thread whenever possible...




          So, when dispatching synchronously from a queue, it actually can end up running that code on the same thread (unless you’re dispatching from a background queue to the main queue). Consider:



          let queue = DispatchQueue.global()
          let queue2 = DispatchQueue(label: "queue2")

          queue.async
          print(1, Thread.current)
          queue2.sync
          print(2, Thread.current)

          print(3, Thread.current)



          That second print statement will show that even though you have a completely different queue, it may, as part of the aforementioned sync optimization, run the code on the current thread. The same it true if that inner sync call was to the same queue to which the outer block was dispatched.



          Now, when looking at the result of this optimization, it feels like this is just like the serial queue scenario, but it’s not. A serial queue only allows one dispatched task to run at a time, and thus the attempt to dispatch synchronously (blocking the current thread until the dispatched block runs) to itself is, by definition, a deadlock.



          But the concurrent queue dispatching to itself is not a deadlock, even though, because of this sync optimization, it may end up running the code on the same thread.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 8 at 16:46

























          answered Dec 22 '18 at 2:13









          RobRob

          307k51580751




          307k51580751












          • but I print [NSThread currentThread] it's same thread.

            – pangyulei
            Apr 8 at 13:52











          • Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

            – Rob
            Apr 8 at 16:29

















          • but I print [NSThread currentThread] it's same thread.

            – pangyulei
            Apr 8 at 13:52











          • Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

            – Rob
            Apr 8 at 16:29
















          but I print [NSThread currentThread] it's same thread.

          – pangyulei
          Apr 8 at 13:52





          but I print [NSThread currentThread] it's same thread.

          – pangyulei
          Apr 8 at 13:52













          Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

          – Rob
          Apr 8 at 16:29





          Correct. The sync method will, as an optimization, run code on the current thread if it can. I’ve attempted to clarify my answer above.

          – Rob
          Apr 8 at 16:29



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53293965%2fwhy-concurrentqueue-sync-dont-cause-deadlock%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

          Edmonton

          Crossroads (UK TV series)