Concurrency in Golang[Part-4]

Photo by Chinmay B on Unsplash

Concurrency in Golang[Part-4]

Channels in control flow

We are almost done with the discussion about the channel. The last thing that I wanted to discuss is how to handle control flow in channels. we are going to discuss the following.

  • IF statement

  • For Loop

  • Select statements.

func main() {
    wg := &sync.WaitGroup{}
    ch := make(chan int,1)

    wg.Add(2)
    go func (ch chan int, wg *sync.WaitGroup) {
        if msg, ok := <- ch; ok {
            fmt.Println(msg, ok) // receiveing the message from channel
        }
        wg.Done()
    }(ch,wg)
    go func (ch chan int, wg *sync.WaitGroup) {
        // close(ch);
        ch <- 42 // sending the message from channel
        wg.Done()
    }(ch,wg)

    wg.Wait()
}

For loop

func main() {
    wg := &sync.WaitGroup{}
    ch := make(chan int,1)

    wg.Add(2)
    go func (ch chan int, wg *sync.WaitGroup) {
        // we are using this for loop show that we can address the issue where we don't know the exact number of message going to come in.
        for msg := range ch {
            fmt.Println(msg)
        }
        //for i := 0; i < 10; i++ {
            //fmt.Println(<-ch)
        //}
        wg.Done()
    }(ch,wg)
    go func (ch chan int, wg *sync.WaitGroup) {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
        wg.Done()
    }(ch,wg)

    wg.Wait()
}

Select Statements

Select Statements are similar to switch statements in their syntax. But in the select statement, we check either send or receive from a channel.

ch1 := make(chan int)
ch2 := make(chan string)
select {
    case i := <-ch1:
        ...
    case ch2 <- "hello":
        ...
}

Here in the above code in the first case, we are checking if we receive the message from ch1 into the variable i and in another case we are sending a string hello to the ch2 .

Now if one of the channels is available to act so if we have a message waiting on ch1 or if we waiting to send a message on ch2 then that case will be taken. If both of the cases are available then Randamoly decided which case going to fire there is no pre-determined order, unlike switch statement where the first case that matches gets acted upon. In select statement, there is no pre-determined order if multiple cases can be acted upon at the same time.

Another thing about select statement if you see the above code. Here select statement will block until it acts in one of those cases. So if there is no message on ch1 and ch2 is not ready for the message we are going to stop the execution of the current goroutine until we receive the message from ch1 or send a message from ch2 . So entire goroutine is going to stop here until we get one of those conditions. This is what we call a blocking select statement. And make it non-blocking select we can add a default case .

ch1 := make(chan int)
ch2 := make(chan string)
select {
    case i := <-ch1:
        ...
    case ch2 <- "hello":
        ...
    default:
        // use default case for non-blocking select
}

Did you find this article valuable?

Support adityakmr by becoming a sponsor. Any amount is appreciated!