SoFunction
Updated on 2025-03-05

How to terminate multiple for select loop nesting methods

Category Description

How to terminate for select loop nesting? On code:

    stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {
            ("writed ", i)
            ( * 1)
        }

        close(stop)
        ("stop closed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop:
                ("recv 1")
                break stop1
            default:

                ("A 1 default...")

                for {
                    select {
                    case <-stop:
                        ("recv 2")
                        break stop1
                    default:
                        ("A 2 default...")
                        ( * 1)
                    }
                }
            }
        }

        ("A End")
    }()

    ("Close", stop == nil)
    for i := 1; i < 10; i++ {
        ( * 1)
        ("ch==nil: ", stop == nil, "   num=", ())
    }

As mentioned above, both the inside and the outside monitor the stop. After the inner layer receives the signal, stop1 is directly terminated, and the entire process ends normally. The effects are as follows:
speed running:

Closed false
A 1 default...
A 2 default...
writed  1
A 2 default...
writed  2
ch==nil:  false    num= 3
ch==nil:  false    num= 3
A 2 default...
stop closed.
recv 2
A End
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1

It is also possible to terminate the inner layer first:

    stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {

            ("writed ", i)
            ( * 1)
        }

        close(stop)
        ("stop closed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop: // You can also receive a signal here                ("recv 1")
                break stop1
            default:

                ("A 1 default...")
            stop2:
                for {
                    select {
                    case <-stop: // You can receive a signal here                        ("recv 2")
                        break stop2 // Change to terminate the inner layer                    default:
                        ("A 2 default...")
                        ( * 1)
                    }
                }

                ("A 2 stop...")
            }
        }

        ("A End")
    }()

    ("Close", stop == nil)
    for i := 1; i < 10; i++ {
        ( * 1)
        ("ch==nil: ", stop == nil, "   num=", ())
    }

As mentioned above, the inner layer terminates its own logic stop2 first, and the outer layer terminates accordingly, ending normally. The effects are as follows:

speed running:

Closed false
writed  1
A 1 default...
A 2 default...
writed  2
ch==nil:  false    num= 3
A 2 default...
A 2 default...
ch==nil:  false    num= 3
stop closed.
recv 2
A 2 stop...
recv 1
A End
ch==nil:  false    num= 2
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1

If it is not based on a shutdown operation but a write, can both the inner and outer layers be received? Answer: I will only receive it once.

stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {
            //ch <- i
            ("writed ", i)
            ( * 1)
        }

        stop <- struct{}{}// close(stop)
        ("stop writed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop: // No signal was received here                ("recv 1")
                break stop1
            //case data := <-ch:
            //    ("A  data=", data)
            default:

                ("A 1 default...")
            stop2:
                for {
                    select {
                    case <-stop: // You can receive a signal here                        ("recv 2")
                        break stop2 // Change to terminate the inner layer                    default:
                        ("A 2 default...")
                        ( * 1)
                    }
                }

                ("A 2 stop...")
            }
        }

        ("A End")
    }()

    ("stop == nil: ", stop == nil)
    for i := 1; i < 10; i++ {
        ( * 1)
        ("ch==nil: ", stop == nil, "   num=", ())
    }

    close(stop)
    ("stop is closed,", stop == nil)

speed running:

stop == nil:  false
writed  1
A 1 default...
A 2 default...
A 2 default...
writed  2
ch==nil:  false    num= 3
recv 2
A 2 stop...
A 1 default...
A 2 default...
stop writed.
ch==nil:  false    num= 3
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
A 2 default...
ch==nil:  false    num= 2
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
stop has been closed, false

Summarize

When the trigger condition needs to be completely terminated, directly terminate the outermost for select to achieve the purpose of all the loops nested under it.

This is the article about how go to terminate multiple for select loop nesting methods. For more related go to terminate loop nesting, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!