This is the fifth video of this section channels in the previous video we looked at new taxes in this
video well first understand how channels work and how we could use it.
We'll look at Buffer channels and directional channels.
We'll also see how to use the select statement for this will make a small app that will send two messages
to the same go routine which will print them an exit.
If it doesn't receive anything else in five seconds channels are the second primitive and the language
allows us to write concurrent applications.
We've talked a bit about channels in the communicating sequential processes section.
Channels are the way we communicate between processes.
We could be sharing a memory location and using me taxes to control the processes access but channels
provide us with a more natural way to handle concurrent applications.
That also produces better concurrent designs in our programs working with many go routines.
Seems pretty difficult.
We can't create some synchronization between them.
The order of execution could be irrelevant as soon as they are synchronized channels are the second
key feature to write concurrent applications in.
Go a TV channel in real life is something that connects an emission from a studio to millions of TV's
which acts as the receivers channels in go work in a similar fashion one or more go routines can work
as emitters and one or more guy routine can act as receivers.
One morphing channels by default block the execution of Go routines till something is received it's
as if our favorite TV show delays the emission until we turn the TV on so we don't miss anything.
How is this done in go.
Let's see this open the main door go file and add our main function to create channels in go.
We use the same syntax that we use to create slices the make keyword is used to create a channel and
we have to parse the keyword Chan am a type that the channel will transport in this case strings.
With this we have a blocking channel with the name channel.
Next we launch a go routine that sends the message Hello well to the channel.
This is indicated by the intuitive arrow that shows the flow the hello world text going to a channel.
This works like an assignment in a variable so we can only pass something to a channel by first writing
the channel then the arrow and find its value to pass.
We cannot write Hello world followed by the intuitive arrows and then channel in this way.
As we mentioned earlier this channel is blocking the execution of Go routines and send a message received.
In this case the execution of the main function is stopped until a message from the launch to go routines
reaches the other end of the channel in the line message code on equals intuitive arrow channel.
In this case the arrow points in the same direction but it is placed before the channel indicating the
data is being extracted from the channel and assigned to a new variable called message.
Using the new assignment operator the AI's colon equals.
In this case we don't need to use a weight group to synchronize the main function with the created go
routines as a default nature of channels is to block until data is received.
But does it work the other way round.
If there is no receiver when the go routine sends a message does it continue.
Let's edit the example we wrote here to see this let me replace this with the modified code.
Perfect.
Now we're going to use a sleep function again in this case we print a message when they go routine is
finished.
The big difference is in the main function.
Now we wait one second before we listen to the channel for data.
It's time to save the file and run the program moved to the terminal and run the command go run main
dot go the output can differ because again there is no arguments in the order of execution but now we
can see that no message is printed until one second is passed.
After the initial delay we start listening to the channel take the data and print it.
So the emitter also has to wait for a cue from the other side of the channel to continue its execution.
To recap channels our ways to communicate between go routines by sending data through one end and receiving
at the other like a pipe in the default state and emit a go routine will block its execution until a
receiver guy routine takes the data.
The same goes for a receiver guy routine which will block until some emitter sends data through the
channel.
So you can have passive listeners waiting for data or passive emitters waiting for listeners.
Now let's step ahead and learn about buffered channels.
A buffer channel works in a similar way to default on buffer channels.
You can also pass and take values from them by using the arrows.
But unlike UN buffer channels senders don't need to wait until some guy routine picks the data that
they are sending.
Let's open our main door go file and add the main function.
Now this example is like the first example we use for channels but now we've set the capacity of the
channel to 1 in the make statement.
With this we tell the compiler this channel has a capacity of one string before getting blocked.
So the first string doesn't block the emitter but the second would let's run this example First save
the file and navigate to the terminal execute the command go run main dot go.
Now we can run this small program as many times as we want.
The output would always be in the same order.
This time we've launched the concurrent function and waited for one second.
Previously the anonymous function wouldn't continue until the second it passed and someone can pick
the sent data.
In this case with a buffer channel the data is held in the channel or freeze the go routine to continuous
execution.
In this case the go routine is always finishing before the White time passes this new channel has a
size of 1 so a second message would block the go routine execution let's go back to the coat file and
make the changes modify the code by adding malign second channel to the go function
after the modifications.
Make sure you make the changes here we add a second hello well to message and we provide it with an
index now close the file and get back to the terminal to check the output execute the previous command
again.
And here's the output.
Hello World 1 indicating that we've just taken one message from the channel buffer.
We've printed it and the main function finished for the launch to go routine could finish the go routine
got blocked when sending the second message and couldn't continue until the other end took the first
message.
Then it print so quickly that it doesn't have time to print the message to show the ending of the go
routine.
If you keep executing the program on the console sooner or later these scheduler will finish the go
routine execution before the main thread.
Now the next type of channels need to discuss are the directional channels.
One call feature about go channels is that when we use them as parameters we can restrict their directionality
so that they can only be used to send or to receive.
The compiler will complain if a channel is used in the restricted direction.
This feature applies a new level of static typing to go ups and makes code more understandable and more
readable.
We'll take a simple example with channels let us add the code for this to our main dot go file within
the directional channel folder and here's the code which we'll be using for this example the line where
we launched the new go routine that is go func H an intuitive arrow string states that the channel pass
to this function can only be used as an input channel and you can't listen to it.
We can also pass a channel that will be used as receiver channel only let's have the code for this as
you can see the arrow is on the opposite side of the keyword channel indicating and extracting operation
from the channel.
Keep in mind that the channel arrow always points left to indicate a receiving channel.
It must go on the left and to indicate and inserting channel it must go on the right.
If we tried to send a value through this receive only channel the compiler will complain about it.
Let's try this at the line c h followed by intuitive arrow and in double quotes Hello this function
has a receive only channel that we will try to use to send the message Hello through.
Let's see what the compiler says Save the file and move to the terminal execute the program.
It doesn't like it and asks us to correct it.
Now the code is even more readable and safe and we've just placed an arrow in front or behind the channel
argument.
Now let's have a look at the select statement the select statement is also a key feature and go.
It's used to handle more than one channel input within a go routine.
In fact it opens lots of possibilities in these select structure.
We asked for program to choose between one or more channels to receive that data.
We can say this data in a variable and make something with it before finishing the select the select
structure is just executed once.
It doesn't matter if it is listening to more channels it will be executed only once and the code will
continue executing.
If we wanted to handle the same channels more than once we have to put in a for loop we'll make a small
app that will send messages hello and the message goodbye to the same go routine it will print them
and exit.
If it doesn't receive anything else in five seconds this diagram gives a clear picture of how our app
work.
Now let's move back to our main dot go file and here will first make a generic function that sends a
string over a channel let's out the code for this.
Now we can send a string over a channel by simply calling the send string method.
It's time for the receiver.
The receiver will take messages from both channels.
The one that sends hello messages and the one that sends goodbye messages.
This is what you saw in the previous diagram.
Next we had the code for the receiver function let's start with the arguments.
This function takes three channels to receiving channels.
I want to send something through it.
Then it starts an infinite loop with the four keyword.
This way we can keep listening to both channels forever inside the scope of select block.
We have to use a case for each channel we want to handle.
Have you realized how similar it is to the switch statement.
Let's see the three cases step by step.
The first case takes incoming data from the hello CHF argument and saves it in a variable called message.
Then it prints the contents of this variable.
The second case takes the incoming data from the goodbye c h arguments and saves in a variable called
Message 2.
Then it also prints the contents of this variable.
The third case is quite interesting.
It calls a time function.
After that if we check its signature it accepts a time and duration value and returns are receiving
channel dates receiving channel will receive a time the value of time after the specified duration is
passed.
In our example we use the channel it returns as a timeout because to select restarted after each handle
the timer is restarted too.
This is a very simple way to set a time or two ago routine waiting for the response of one or many channels.
Everything is ready for the main function so let's add our main function
again step by step.
We created the three channels that will need in this exercise.
Then we launched our receiver function in a different routine.
This go routine is handled by go's scheduler and our program continues.
We launched a new go routine to send the message Hello to the hello CHF arguments.
Again this is going to occur eventually when the go scheduler decides our program continues again and
waits for a second.
In this break go scheduler will have time to execute the receiver and the first message if it hasn't
done so yet.
The Hello message will appear on the console during the break.
A new message is sent over the goodbye channel with the goodbye text in a new go routine and our program
continues again to a line where we wait for an incoming message in the quit C argument we've launched
three go routines already.
The receiver that is still running the first message and had finished when the message was handled by
the select statement and the second message was printed almost immediately and had finished too.
So just the receiver is running at this moment and if it doesn't receive any other message in the following
two seconds it will handle the incoming message from the time structure after Channel type.
Print a message to say that it is quitting in the true to the quit C H and break the infinite loop where
it was looping save the file and let us run the small lab execute the command go run main dot go now.
The result may not be very impressive but the concept is clear.
We can handle many incoming channels in the same go routine by using the select statement superb The
last feature about channels that we'll see is ranging over channels we're talking about the range keyword.
We've used it extensively to range over lists and we can use it to range over a channel to open the
main don't go file and add the main function now.
In this case we've created an unbundled channel but it would work with a buffered one too.
We launched our function in the new go routine that sends the number one over a channel.
Wait a second sends a number two and closes the channel the last step is to range over the channel.
The syntax is quite similar to a list range.
We store the incoming data from the channel in the variable v and we print this variable to the console.
The range keeps iterating until the channel is closed.
Taking data from the channel can you guess the output mister or program.
Don't worry I'll run and show it to you right now Let's navigate to a terminal and execute the RUN command.
Again not very impressive.
It prints the number 1.
Then wait a second.
Prints in number 2 and exits the application according to the design of this concurrent app.
The range was iterated over possible incoming data from the channel until the concurrent go routine
closes the channel.
At that moment the range finishes and the app connects it.
Range is very useful in taking data from a channel and it is commonly used in fan patterns where many
different go routine send data to the same channel.
Cool in this video we've learned about channels in go in the next video we'll write a concurrent counter
like the one we wrote in New Texas.