memory leak in solution for Exercise: Equivalent Binary Trees?How does select work when multiple channels are involved?Anatomy of a “Memory Leak”Are memory leaks ever ok?Creating a memory leak with JavaGo Tour Exercise: Equivalent Binary TreesHow to check a channel is closed or not without reading it?Using multiple Goroutines on Go Tour Equivalent Binary TreesGolang channels using select doesn't stopHow to stop a goroutine that is listening for RethinkDB changefeeds?two way communication through channels in golangSignal goroutines to stop with channel close

How do you name this compound using IUPAC system (including steps)?

Could Europeans in Europe demand protection under UN Declaration on the Rights of Indigenous Peoples?

Integration using partial fraction is wrong

Are there any satellites in geosynchronous but not geostationary orbits?

Are there foods that astronauts are explicitly never allowed to eat?

How to tell readers that I know my story is factually incorrect?

Applying for jobs with an obvious scar

What's a German word for »Sandbagger«?

"Je suis petite, moi?", purpose of the "moi"?

How do you send money when you're not sure it's not a scam?

How to belay quickly ascending top-rope climbers?

A spacecraft is travelling at X units per hour. But relative to what exactly? Does it depend on orbit? How?

Company looks for long-term employees, but I know I won't be interested in staying long

Project Euler # 25 The 1000 digit Fibonacci index

Why are flying carpets banned while flying brooms are not?

Do Australia and New Zealand have a travel ban on Somalis (like Wikipedia says)?

Transistor power dissipation rating

Why would word of Princess Leia's capture generate sympathy for the Rebellion in the Senate?

Authorship dispute on a paper that came out of a final report of a course?

Equality of complex numbers in general

How did Jayne know when to shoot?

How can I automate this tensor computation?

Why does a tetrahedral molecule like methane have a dipole moment of zero?

Why is regex [0-9]0,2 not greedy in sed?



memory leak in solution for Exercise: Equivalent Binary Trees?


How does select work when multiple channels are involved?Anatomy of a “Memory Leak”Are memory leaks ever ok?Creating a memory leak with JavaGo Tour Exercise: Equivalent Binary TreesHow to check a channel is closed or not without reading it?Using multiple Goroutines on Go Tour Equivalent Binary TreesGolang channels using select doesn't stopHow to stop a goroutine that is listening for RethinkDB changefeeds?two way communication through channels in golangSignal goroutines to stop with channel close






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















(https://github.com/golang/tour/blob/master/solutions/binarytrees_quit.go) for Exercise: Equivalent Binary Trees
Supposed we have two simple equivalent binary trees "1 3 5" and "2 3 5". When two goroutines "Walk" walks at leaf "1" and "2" concurrently,



if v1 != v2 
return false



this condition in function Same will be true and



close(quit)



will run.



func walkImpl(t *tree.Tree, ch, quit chan int) 
if t == nil
return

walkImpl(t.Left, ch, quit)
select
case ch <- t.Value:
// Value successfully sent.
case <-quit:
return

walkImpl(t.Right, ch, quit)



Channel "quit" will receive message and the second case of select statement will execute. And then it will go back to the upper level function "walkImpl" and keep on running the last line walkImpl(t.Right, ch, quit). So is there goroutine leak under the circumstance, cause channel "quit" is already read out, which can't be read again in the upper level? Function "Walk" also can't go back to "close" handler.










share|improve this question






























    3















    (https://github.com/golang/tour/blob/master/solutions/binarytrees_quit.go) for Exercise: Equivalent Binary Trees
    Supposed we have two simple equivalent binary trees "1 3 5" and "2 3 5". When two goroutines "Walk" walks at leaf "1" and "2" concurrently,



    if v1 != v2 
    return false



    this condition in function Same will be true and



    close(quit)



    will run.



    func walkImpl(t *tree.Tree, ch, quit chan int) 
    if t == nil
    return

    walkImpl(t.Left, ch, quit)
    select
    case ch <- t.Value:
    // Value successfully sent.
    case <-quit:
    return

    walkImpl(t.Right, ch, quit)



    Channel "quit" will receive message and the second case of select statement will execute. And then it will go back to the upper level function "walkImpl" and keep on running the last line walkImpl(t.Right, ch, quit). So is there goroutine leak under the circumstance, cause channel "quit" is already read out, which can't be read again in the upper level? Function "Walk" also can't go back to "close" handler.










    share|improve this question


























      3












      3








      3








      (https://github.com/golang/tour/blob/master/solutions/binarytrees_quit.go) for Exercise: Equivalent Binary Trees
      Supposed we have two simple equivalent binary trees "1 3 5" and "2 3 5". When two goroutines "Walk" walks at leaf "1" and "2" concurrently,



      if v1 != v2 
      return false



      this condition in function Same will be true and



      close(quit)



      will run.



      func walkImpl(t *tree.Tree, ch, quit chan int) 
      if t == nil
      return

      walkImpl(t.Left, ch, quit)
      select
      case ch <- t.Value:
      // Value successfully sent.
      case <-quit:
      return

      walkImpl(t.Right, ch, quit)



      Channel "quit" will receive message and the second case of select statement will execute. And then it will go back to the upper level function "walkImpl" and keep on running the last line walkImpl(t.Right, ch, quit). So is there goroutine leak under the circumstance, cause channel "quit" is already read out, which can't be read again in the upper level? Function "Walk" also can't go back to "close" handler.










      share|improve this question
















      (https://github.com/golang/tour/blob/master/solutions/binarytrees_quit.go) for Exercise: Equivalent Binary Trees
      Supposed we have two simple equivalent binary trees "1 3 5" and "2 3 5". When two goroutines "Walk" walks at leaf "1" and "2" concurrently,



      if v1 != v2 
      return false



      this condition in function Same will be true and



      close(quit)



      will run.



      func walkImpl(t *tree.Tree, ch, quit chan int) 
      if t == nil
      return

      walkImpl(t.Left, ch, quit)
      select
      case ch <- t.Value:
      // Value successfully sent.
      case <-quit:
      return

      walkImpl(t.Right, ch, quit)



      Channel "quit" will receive message and the second case of select statement will execute. And then it will go back to the upper level function "walkImpl" and keep on running the last line walkImpl(t.Right, ch, quit). So is there goroutine leak under the circumstance, cause channel "quit" is already read out, which can't be read again in the upper level? Function "Walk" also can't go back to "close" handler.







      go memory-leaks






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 26 at 11:05









      Flimzy

      43.5k13 gold badges71 silver badges109 bronze badges




      43.5k13 gold badges71 silver badges109 bronze badges










      asked Mar 26 at 11:03









      Yu LiuYu Liu

      182 bronze badges




      182 bronze badges






















          1 Answer
          1






          active

          oldest

          votes


















          2














          When multiple goroutines are targeted with a cancellation signal, most often it is done by closing a channel, and not sending a value on the channel. Receiving from a closed channel can proceed immediately, no matter how many goroutines do that. A value sent on a channel can be received at most once, so it is not suitable to signal multiple goroutines with a value. Spec: Receive operator:




          A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.




          Now, if you close the quit channel, that does not guarantee your function will return immediately.



          First, you recurse down to the left child without checking quit, which call will do the same (until a nil left child is reached).



          Second, if a value can be sent on ch, then both cases are ready and thus select chooses one of them randomly, which may or may not be the quit case. For details, see How does select work when multiple channels are involved?



          If you want to avoid these, you should add a non-blocking quit check as the first thing in your function:



          func walkImpl(t *tree.Tree, ch, quit chan int) 
          select
          case <-quit:
          return
          default: // This empty default makes it a non-blocking check


          if t == nil
          return

          walkImpl(t.Left, ch, quit)
          select
          case ch <- t.Value:
          // Value successfully sent.
          case <-quit:
          return

          walkImpl(t.Right, ch, quit)



          Now one could ask if we still need the quit case in the second select since we've already checked it first thing in walkImpl(). The answer is that you should keep that too, because if sending on ch would block (e.g. the consumer would be shut down when quit is closed), that send operation could block forever. This way (when quit is closed) it is guaranteed that the function returns.






          share|improve this answer
























            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%2f55355577%2fmemory-leak-in-solution-for-exercise-equivalent-binary-trees%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









            2














            When multiple goroutines are targeted with a cancellation signal, most often it is done by closing a channel, and not sending a value on the channel. Receiving from a closed channel can proceed immediately, no matter how many goroutines do that. A value sent on a channel can be received at most once, so it is not suitable to signal multiple goroutines with a value. Spec: Receive operator:




            A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.




            Now, if you close the quit channel, that does not guarantee your function will return immediately.



            First, you recurse down to the left child without checking quit, which call will do the same (until a nil left child is reached).



            Second, if a value can be sent on ch, then both cases are ready and thus select chooses one of them randomly, which may or may not be the quit case. For details, see How does select work when multiple channels are involved?



            If you want to avoid these, you should add a non-blocking quit check as the first thing in your function:



            func walkImpl(t *tree.Tree, ch, quit chan int) 
            select
            case <-quit:
            return
            default: // This empty default makes it a non-blocking check


            if t == nil
            return

            walkImpl(t.Left, ch, quit)
            select
            case ch <- t.Value:
            // Value successfully sent.
            case <-quit:
            return

            walkImpl(t.Right, ch, quit)



            Now one could ask if we still need the quit case in the second select since we've already checked it first thing in walkImpl(). The answer is that you should keep that too, because if sending on ch would block (e.g. the consumer would be shut down when quit is closed), that send operation could block forever. This way (when quit is closed) it is guaranteed that the function returns.






            share|improve this answer





























              2














              When multiple goroutines are targeted with a cancellation signal, most often it is done by closing a channel, and not sending a value on the channel. Receiving from a closed channel can proceed immediately, no matter how many goroutines do that. A value sent on a channel can be received at most once, so it is not suitable to signal multiple goroutines with a value. Spec: Receive operator:




              A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.




              Now, if you close the quit channel, that does not guarantee your function will return immediately.



              First, you recurse down to the left child without checking quit, which call will do the same (until a nil left child is reached).



              Second, if a value can be sent on ch, then both cases are ready and thus select chooses one of them randomly, which may or may not be the quit case. For details, see How does select work when multiple channels are involved?



              If you want to avoid these, you should add a non-blocking quit check as the first thing in your function:



              func walkImpl(t *tree.Tree, ch, quit chan int) 
              select
              case <-quit:
              return
              default: // This empty default makes it a non-blocking check


              if t == nil
              return

              walkImpl(t.Left, ch, quit)
              select
              case ch <- t.Value:
              // Value successfully sent.
              case <-quit:
              return

              walkImpl(t.Right, ch, quit)



              Now one could ask if we still need the quit case in the second select since we've already checked it first thing in walkImpl(). The answer is that you should keep that too, because if sending on ch would block (e.g. the consumer would be shut down when quit is closed), that send operation could block forever. This way (when quit is closed) it is guaranteed that the function returns.






              share|improve this answer



























                2












                2








                2







                When multiple goroutines are targeted with a cancellation signal, most often it is done by closing a channel, and not sending a value on the channel. Receiving from a closed channel can proceed immediately, no matter how many goroutines do that. A value sent on a channel can be received at most once, so it is not suitable to signal multiple goroutines with a value. Spec: Receive operator:




                A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.




                Now, if you close the quit channel, that does not guarantee your function will return immediately.



                First, you recurse down to the left child without checking quit, which call will do the same (until a nil left child is reached).



                Second, if a value can be sent on ch, then both cases are ready and thus select chooses one of them randomly, which may or may not be the quit case. For details, see How does select work when multiple channels are involved?



                If you want to avoid these, you should add a non-blocking quit check as the first thing in your function:



                func walkImpl(t *tree.Tree, ch, quit chan int) 
                select
                case <-quit:
                return
                default: // This empty default makes it a non-blocking check


                if t == nil
                return

                walkImpl(t.Left, ch, quit)
                select
                case ch <- t.Value:
                // Value successfully sent.
                case <-quit:
                return

                walkImpl(t.Right, ch, quit)



                Now one could ask if we still need the quit case in the second select since we've already checked it first thing in walkImpl(). The answer is that you should keep that too, because if sending on ch would block (e.g. the consumer would be shut down when quit is closed), that send operation could block forever. This way (when quit is closed) it is guaranteed that the function returns.






                share|improve this answer















                When multiple goroutines are targeted with a cancellation signal, most often it is done by closing a channel, and not sending a value on the channel. Receiving from a closed channel can proceed immediately, no matter how many goroutines do that. A value sent on a channel can be received at most once, so it is not suitable to signal multiple goroutines with a value. Spec: Receive operator:




                A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.




                Now, if you close the quit channel, that does not guarantee your function will return immediately.



                First, you recurse down to the left child without checking quit, which call will do the same (until a nil left child is reached).



                Second, if a value can be sent on ch, then both cases are ready and thus select chooses one of them randomly, which may or may not be the quit case. For details, see How does select work when multiple channels are involved?



                If you want to avoid these, you should add a non-blocking quit check as the first thing in your function:



                func walkImpl(t *tree.Tree, ch, quit chan int) 
                select
                case <-quit:
                return
                default: // This empty default makes it a non-blocking check


                if t == nil
                return

                walkImpl(t.Left, ch, quit)
                select
                case ch <- t.Value:
                // Value successfully sent.
                case <-quit:
                return

                walkImpl(t.Right, ch, quit)



                Now one could ask if we still need the quit case in the second select since we've already checked it first thing in walkImpl(). The answer is that you should keep that too, because if sending on ch would block (e.g. the consumer would be shut down when quit is closed), that send operation could block forever. This way (when quit is closed) it is guaranteed that the function returns.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Mar 26 at 13:14

























                answered Mar 26 at 12:03









                iczaicza

                192k28 gold badges404 silver badges423 bronze badges




                192k28 gold badges404 silver badges423 bronze badges
















                    Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







                    Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















                    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%2f55355577%2fmemory-leak-in-solution-for-exercise-equivalent-binary-trees%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

                    SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                    용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

                    155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해