Concurrency and Channel in Go

What is Concurrency?

Concurrency is a core feature, and Goroutines provide a lightweight way to achieve asynchronous and parallel execution In summary, concurrency is about managing and overlapping the execution of multiple tasks, often on a single processor, to enhance efficiency and responsiveness. Synchronous: Unlike concurrency in synchronous one task executes at a time, the next starts when the current is done. It is the ability to perform multiple tasks at the same time. Typically, our code is executed on line at a time, one after the other. This is called Sequential or Synchronous execution.

In go concurrency can be achieved using simple go keyword.

// example 
go functionName()

In the example code functionName is a function which will be executed concurrently with the rest of the code. In Golang the go keyword is used to create a new goroutine which is a lightweight execution thread and a function that executes concurrently with the rest of the program. Remember as goroutine is concurrent in nature and not synchronous they don't return any value. So you may have a question, How do we share data between these functions or goroutines here comes Channel.

What is Channel?

Channel is unique concept in Golang and important feature of the language. Channels are the way to communicate between goroutines and send data to each other. It is the one of the most powerful feature that makes go unique from other language. It enable our program to share memory by communication.

How to create a Channel?

In Go, we use make() function to create a channel.

channelName := make(chan int) // channel of integer type

Channel Operations

Send Data to Channel

channelName <- data // syntax to send data to channel
number <- 1
message <- "Hello World"

Receive data from channel

val := <- channelName 
num := <- number
msg := <-message

How Channel share data between goroutines?

Internally reading from the go channels are implemented using FIFO(First in First out) queue, so first goroutine ask for the reading from the channel received it first. For example if there is a channel c and two goroutines g1 and g2 they are implemented in such a way that they access channel c, perform some action on it and sleep for 100 milliseconds. So in this case when g1 asked for c, performed action and then sleeps for 100 milliseconds same goes for g2 so and process kept going on they both wakeup after 100 milliseconds and then ask for reading the channel, so in this case how program will decide whom to give channel first, that's where FIFO queue comes in, it manages all the ask request for that particular channel and provides channel in order. Here is the code example

func main(){
  var Ball int
  table := make(chan int)
  go player(table) // goroutine 1
  go player(table) // goroutine 2

  table <- Ball // send intial value to channel
  time.Sleep(100 * time.Millisecond)
  <-table 
}
func player(table chan int){
   for{
     ball := <-table
     ball++
     time.Sleep(100* time.Millisecond)
     table <- ball
   }
}

In the above example there is two go routine executing player function and requesting for table channel to read and then sleep for 100 milliseconds and then write new value to the channel by incrementing by 1 using increment ++ operator.

If you want to understand go concurrency visually so you can watch this video by Ivan Danyliuk :-

For notes you can refer to my Github repo:-

Thanks for reading:)

1
Subscribe to my newsletter

Read articles from Harshit Tripathi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Harshit Tripathi
Harshit Tripathi

Coding