Learning Golang: Introduction to Concurrency Patterns, goroutines and channels

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my name is mario welcome to another learning go video this is the introduction to concurrency patterns where we are going to be covering specifically go routines channels and all the needed keywords that we have to use for defining those values let's start with concurrency what is concurrency concurrency is the composition of independently executing processes in our rewards it also is about dealing with lots of items or things at once concurrency is usually confused with parallelism is not the same so what is parallelism then parallelism is the simultaneous execution of computations possibly related it's about doing lots of things at once so if you use an analogy for defining concurrency we can think of a coffee shop for example where you have a coffee machine and we have your customers just lining up for getting coffee each one of these customers is going to take a while to decide what kind of coffee they want depending on what their needs and maybe their dietary habits or the things right maybe somebody want milk somebody wants iced coffee and whatnot when we're thinking about concurrency using this analogy the way i like to define it is that we have all of these customers line up for using or for getting coffee therefore all of them are trying to use this resource that is the coffee machine if we want to somehow make a good use of our time because like i said each one of these customers is taking some time to decide what they want perhaps we can add a new line that includes customers that again will take some time but also at the same time there is a way to somehow share this coffee machine between the two the two lines for doing that we need a thing for coordination now if we go and look at this using the same analogy but now talking about about parallelism the idea will be similar we have a coffee machine and we have our users and they think about the coffee they want and what not but the biggest difference is now that now we are not sharing a coffee machine now there is a dedicated coffee machine for the customers that happen to be lining up for that specific uh coffee machine therefore there is no concurrency between the two of them so in go there are two things like i mentioned in the beginning there's a thing called go routines and there is a thing called channels they are used for defining this concept of concurrency and building uh code around the programs and applications that happen to be concurrent so what is a go routine ago routine is the independently executed function it uses the goal keyword for launching the function if we see at this example that i'm going to show you next you will notice how this is implemented in real life as usual the link to all of these examples will be in the description so you can check it out and playing with it now let me show you the example or first of all i need to run change to the folder where i have it and the code is extremely simply like i told you before there is a go keyword and the function that we are going to be using for running it as a go routine now this really as you may imagine is not doing anything in particular and really it's not going to be printing out this message at all and the reason being is that because there is no way to wait until this function completes all right so far in this code we don't have a way to indicate hey maine can you please wait until hello complete therefore main will just go on and exit maybe there are cases where you will see this message printed out but most of the times you are not going to see it and the reason being is that go routines run in like i said uh concurrently so depending on how they are being how they have been executed maybe the the if main access before all the other ones then whatever was happening in the other routines doesn't matter and we will not be computed which in this case will be the print line so what is a channel a channel is a mechanism through which we can send and receive values for example let's say we have these two go routines that happen to be defining a channel and what is going to happen is that in order for the one on the left to receive the value then from the one on the right then the value has to be inside the channel for for getting the value so right now if i if the one on the right is sending the value then the other one will be able to receive the value because somehow uh that's how it's implemented and go so a channel to use it you need to use the key keyword called chan and you need to use the make keyword as well similar to slicers or pointers to types or pointer types and there's this new operator which is the left arrow and it indicates where the data is flowing so for example in this what i have on the screen will be v the value v is going into the channel or is being sent to the channel ch on the other hand if we want to perceive values the channel will be the one sending it therefore the key uh the operator is still left arrow but it's used in a different way it's like we're pulling the values from the channel or if you want to see it from right to left you'll be you're sending the values from channel to the value now let's look at the code and see how this works in in another example in real life so i have my example right here which is again using main and the important bit about this one is that if you notice um i have a comment that says this program is going to panic and the reason is that when in go if there is no go routine that happens to be accessing or interacting with the channel outside of main then it will say that the you know all routines are there is a deadlock because all the routines are as asleep and we're going to be fixing this in in a few moments but i want to show you if you run this example it will fail because like i said nobody is using it the important bit about the channels is like if you remember the animation that i will show you before is that in order for the channel to be used there there has to be something in the channel if there is nothing or nobody sending data to that channel well and we're trying to receive the receive a value then it's going to be failing which is this case which will be a similar situation right here if we move this line above it it will fail no matter what so let's go let's continue so i have another example to show you also related channels that does something similar to what we were doing before but now we are using the go keyword and therefore we're using a go routine i want you to pay attention to these lines for example from line 11 to line 17 which will be here we are launching a new go routine that happens to be using a channel of a string and sending the message hello if i run this what is going to happen is that we are going to be waiting for the message and then as soon as we receive the message we are going to be printing it out the cool thing about this is that i added a timer here to sleep for two seconds to sort of demonstrate what is happening behind the scenes so let's run this example and you will see what i'm trying to say so right here i'm taking a nap and then send in the value so it will be taking a nap and then send it the value but if you notice this one is right here waiting for the message that we're sending inside the go routine now if you compare this to what we had before you will notice that now we have a channel that has been interacted or has been used by a go routine outside of main and therefore is not panicking and therefore is working so let's continue with the other slides so channels by default send uh when you're sending and receiving they will block until the other side is ready which is the example i showed you first when i was using the channel that i was giving and giving us a panic is giving us a panic because nobody else is using that receiver or sender in the second example everything is working because we're accessing that through the go routine that happens to be in anonymous inside the main the main function so by default for these channels this type of channels they will block until something else is using it and this important knowledge because this will make more sense in the in the next examples now there is this concept of buffer channel and buffer channel is similar to what we were describing before there is a channel but happens to be a capacity sort of like when you are creating a slice with capacity it's sort of the same idea and in order for the receiver that is on the left it will have to wait until the values in the on the buffer for accessing it and on the same the same the same idea will be for the one sending it in on in order to send it you still have if you still have capacity for sending values you will still be allowed to continue now the way it works and really the biggest difference is that there is a capacity indicator next to the when you are indicating the chan and the type that you are going to be using other than that it looks more or less like a slice when you're instantiating a slice and one important thing to to notice and remember is that compared to when is we are not using a buffer channel or the on buffer channel this one will be blocking when you're sending and the buffer and the channel is already full which makes sense you cannot send anything you cannot add anything to the to the channel if everything if the capacity is rich and similarly when you're receiving if there is nothing in the channel it will be blocking because obviously you don't have anything to receive now let's look at the example so everything makes more sense so right here i have an example using in a buffer channel basically what i'm trying to demonstrate is that although we are sending data to the channel it will eventually block because it gets full and one important beat that i added here is this comment that depending on how how lucky or unlocked you are you may or may not see this message and i want to show you the output so you can see it you will notice that after i send the second one it will be blocking because the other two are already already the chant the buffer is for the buffer the yeah the buffer channel is full therefore i cannot send any more values but if i'm uh and it's not printing out this line that i was mentioning before so let's look at the if i run it again uh again it happened i mean but if you keep going and continue running this example you will notice that from time to time it actually prints out this so this is sort of like a race condition that we're um experiencing at the moment that we are going to be fixing soon so in a few moments and i will show you how to do that but the idea with the buffer channels is that you can still send messages to a channel for as many capacitive capacity number that you define when it was created and it will continue processing the values on the receiver side but eventually the sender will be stopped because there is no more capacity so sort of the same idea but this is important to differentiate this use use case as well so let's continue with this so what else we have in channel so there are these three keywords that uh you maybe are familiar with already close range and select and close is for closing the channel this means that you are not able to send or receive any more values from that channel range is similar to when we are doing a range in a for loop for example in the slices the difference is that it's going to be pulling the values automatically until the channel is closed and select is a way to coordinate different channels in a way that it sort of acts like acts like a switch so you define a case where you're indicating hey this is the channel that i'm trying to get values from if you can give values then i will i will continue with whatever law you have inside that select case statement and this allows to sort of coordinate and handle multiple routines let me show you so this is the last example i have here for you and this one is using everything that i was showing you before is using buffer channels on buffer channels is using the go routines select range and also close and i have a few examples inside this example to show you how things work the first things that i want to mention to you is that we have these two channels one will be the one for use for producing values and the other one will be used sort of like a way to stop the process or a way to indicate that all the go routines are completed and therefore main can exit because if you remember in the beginning when we were using a go routine it was not printing out the message that we're trying to print and this was because maine was exiting immediately so this is a way to sort of like stop the process until all of the previous go routines are completed so let me show you how this this starts so we have the ch channel that if you notice in the function that i have here this go routine when it's executed it's just literally sending values to the channel five times and then it takes an app every second so every every time it sends a message or a value it will take a one second nap and when it's finished it will close the producer channel now okay that's important to remember let me uh move this a little bit let me put it on the side and on this side so actually now let's close it let's move scroll down a little bit so this side has the important part of the consumer this consumer is using a four an infinite four and probably just to demonstrate how you can use select if we were happy we were trying to interact with more than one channel in this case it's sort of redundant because we are only we only have one channel but if for whatever reason we wanted to define a default action we can define default i don't know maybe oops they should be here it's actually right here it should be maybe defining hey printing and nothing is happening so in that case uh when we are saving oops what the heck so in the case where we are still sleeping and the producer is sleeping it will be printing out printing out nothing has happened default is also another keyboard added only specifically to the select is again is sort of similar to the switch but this works for gore for channels so what i'm trying to do is i'm trying to receive a channel and i'm using an indicator to let me know if the channel is still open because if you remember in the line right here 23 i'm closing the channel this is sort of a way to indicate sort of like a the way type assertion works when you're trying to convert one type to the order if if those are compatible well the idea is sort of similar it tells you if the channel is still open if it's not open obviously it means it was closed and then you can do something with it and i this is where i'm calling again the close keyword that i'm using a little bit down here for um exiting the whole process now if we run this example you will notice that everything works as expected and is doing nothing is happening and just that's okay what is happening is that eventually it will be finishing because if we scroll up and we look for the printing out hopefully i didn't you know reach the maximum buffer on my terminal it looks like i did so let me comment out these lines so you can see the values that we're doing it every single second so i'm receiving one i'm receiving two and receiving three four and eventually i'm exiting because everything is completed now if i go back and use the order keyword which is called range you will notice that in this case the steps are a little bit similar and and the process that we're following is sort of more or less the same but the biggest difference is that we are not using select because we are only using one channel in this example so if i run this again you will see basically the same output uh printing out until from zero to four and exiting now when should you be using one or the other well it depends how many channels you are trying to you know coordinate and why not and more all of this will make more sense when we're actually implementing uh concurrency patterns in go because they use different all these uh basic keywords that are in the language to implement those concurrency patterns so let's jump into the conclusions and i will talk to you in a few seconds so that's it everybody thank you for watching this is the introduction to the concurrency patterns hopefully all of this makes sense i will be covering a specific concurrency patterns in go like finding fan out uh but in parallel not in parallel sequential or concurrent and using the different packages that are available in the standard library as well as some third-party packages and different ways to you know build concurrent programs using go so any comments any questions just let me know and i will and i will talk to you talk to you next time see
Info
Channel: Mario Carrion
Views: 43,936
Rating: undefined out of 5
Keywords: golang, golang concurrency, golang concurrency patterns, golang goroutine, golang channels, golang channel select, golang channel select case, golang fan-in, golang fan-out, golang parallelism, golang buffered channel, golang buffered unbuffered channel, golang design patterns, leargn golang, learn golang concurrency
Id: -xEycsoGoA8
Channel Id: undefined
Length: 17min 47sec (1067 seconds)
Published: Thu Aug 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.