WEBVTT 00:00.480 --> 00:06.720 We're back with the second video of this section go routines in the previous video we learned what concurrency 00:06.720 --> 00:07.270 is. 00:07.470 --> 00:12.270 In this video we'll create our first go routine and then see how to launch anonymous functions as new 00:12.270 --> 00:13.250 guy routines. 00:13.260 --> 00:15.870 We'll also learn to use the weight groups in go. 00:15.870 --> 00:21.450 We achieve concurrency by working with go routines like processes that run applications in a computer 00:21.450 --> 00:22.620 concurrently. 00:22.620 --> 00:28.530 In fact the main loop of go could be considered a go routine to go routines are used in places where 00:28.530 --> 00:30.080 we would use actors. 00:30.270 --> 00:37.870 They execute some logic or die or keep looping if necessary but go routines are not threads we can launch 00:37.870 --> 00:43.910 thousands of concurrent go routines even millions they're incredibly cheap with a small growth stack 00:44.890 --> 00:48.890 we'll use go routines to execute code that we want to work concurrently. 00:49.220 --> 00:54.530 For example three calls to three services to compose a response can be designed concurrently with three 00:54.530 --> 00:59.870 go routines to do the service calls potentially in parallel and a fourth go routine to receive them 01:00.050 --> 01:02.350 and compose the response. 01:02.360 --> 01:07.370 The point here is that if we have a computer with four cause we could potentially run this service corps 01:07.400 --> 01:12.620 in parallel but if we use a one core computer the design will still be correct and the calls will be 01:12.620 --> 01:17.840 executed concurrently in only one core by designing concurrent applications. 01:17.840 --> 01:22.220 We don't need to worry about parallel execution returning to the bike analogy. 01:22.220 --> 01:26.780 We were pushing the pedals of the bike with our two legs that's to go routines concurrently pushing 01:26.780 --> 01:27.860 the pedals. 01:28.280 --> 01:33.920 When we use a tandem we had a total of four go routines possibly working in parallel but we also have 01:33.920 --> 01:36.460 two hands to handle the front and rear brakes. 01:36.500 --> 01:42.600 That's a total of eight go routines for our two threads bike actually we don't pedal when we break and 01:42.600 --> 01:44.280 we don't break and we pedal. 01:44.430 --> 01:47.100 That's a correct concurrent design. 01:47.100 --> 01:51.660 Our nervous system transports the information about when to stop pedaling and when to start braking 01:52.440 --> 01:55.580 in go our nervous system is composed of channels. 01:55.740 --> 01:58.010 We'll see them after playing a bit with go routines first. 01:59.060 --> 02:04.770 Enough of the explanations now let's get our hands dirty for our first go routine we'll print the message 02:04.770 --> 02:12.130 Hallowell world in a go routine let's start right now I've already created a file and named it go routine 02:12.640 --> 02:18.410 where we first need to add the main package and a simple function with the print command running this 02:18.410 --> 02:24.350 small snippet of code will simply output hello world in the console so let's say this file and move 02:24.350 --> 02:25.010 on to the terminal 02:28.060 --> 02:35.990 type the command Go run go routines dot go and here's the output which we wrote in the print statement 02:36.650 --> 02:42.560 Not impressive at all to run it in a new go routine we just need to add the keyword go at the beginning 02:42.560 --> 02:50.130 of the call to the function let's try this get back to the code file and go over here with this simple 02:50.130 --> 02:55.920 word we're telling go to start a new go routine running the contents of the hello world function now 02:55.920 --> 03:04.520 again save the file and navigate to a terminal notice run it what it printed nothing. 03:04.710 --> 03:10.490 Why is that things get complicated when you start to deal with concurrent applications. 03:10.880 --> 03:16.480 The problem is that the main function finishes before he hello world function gets executed let's go 03:16.480 --> 03:24.000 back to the code file and analyze it step by step the main function starts and schedules a new go routine 03:24.000 --> 03:28.920 that will execute me hello world function but the function isn't executed when the function finishes 03:29.310 --> 03:31.800 it's still in the scheduling process. 03:31.800 --> 03:36.390 So our main problem is that the main function has to wait for the go routine to be executed before finishing 03:37.910 --> 03:44.070 so let's pause for a second to give some room to the go routine for this out to the main function time 03:44.130 --> 03:44.730 dot sleep 03:50.460 --> 03:58.260 and in parentheses time dot second now the time dot sleep function effectively sleeps the main go routine 03:58.260 --> 04:05.240 for one second before continuing and exiting if we run this now we must get the message say the file 04:05.360 --> 04:13.330 and get back to a terminal run the go routine again whoops we need to import the package time let's 04:13.330 --> 04:20.020 go back to the code file and do it import in inverted commas time cool. 04:20.130 --> 04:22.300 Let's say the file and run it again. 04:22.500 --> 04:23.630 We again get the output. 04:23.640 --> 04:24.920 Hello world. 04:25.140 --> 04:30.290 I suppose you must have noticed by now the small gap of time where the program is freezing before finishing. 04:30.450 --> 04:35.740 This is the function for sleeping if you're doing a lot of tasks you might want to raise the waiting 04:35.740 --> 04:37.570 time to whatever you want. 04:37.570 --> 04:42.690 Just remember that in any application the main function cannot finish before the rest of the go routines. 04:42.700 --> 04:49.000 Now let's see how we can launch anonymous functions as new go routines we've defined the hello world 04:49.000 --> 04:52.030 function so that it can be launched with a different go routine. 04:52.030 --> 04:56.260 This is not strictly necessary because you can launch snippets of code directly in the function scope 04:56.800 --> 04:58.860 as we did in this piece of code. 04:58.870 --> 05:05.180 This is also valid we've used an anonymous function and we've launched and you go routine using the 05:05.180 --> 05:06.560 go keyword. 05:06.770 --> 05:09.410 Take a closer look at the closing braces of the function. 05:09.410 --> 05:14.900 They're followed by opening and closing parentheses indicating the execution of the function. 05:14.900 --> 05:17.820 We can also pass data to anonymous functions. 05:17.900 --> 05:19.720 Let me show you how to do this. 05:19.910 --> 05:24.430 You need to add message with the keyword string in the Go function and pass the message to the print. 05:24.470 --> 05:29.870 L end function after the brace brackets of the go function at the message in double quotes as Hello 05:29.870 --> 05:31.560 World. 05:31.570 --> 05:33.240 This is also valid. 05:33.370 --> 05:38.950 We have defined an anonymous function that received a string which then printed the received string. 05:38.950 --> 05:44.210 When we called the function in a different go routine we passed the message we wanted to print. 05:44.470 --> 05:45.190 In this sense. 05:45.190 --> 05:47.190 Another example would also be valid. 05:47.200 --> 05:48.600 Let me show you this one. 05:48.760 --> 05:50.490 It's looking a little messy. 05:50.590 --> 05:54.080 Let me ident it probably okay. 05:54.360 --> 05:59.040 In this case we've defined the function within the scope of our main function and stored in a variable 05:59.040 --> 06:01.180 called message printed. 06:01.180 --> 06:05.500 Now we can concurrently print as many messages as we want by using the message print a string signature 06:06.710 --> 06:13.300 it's on to say the file and run the code moved to the terminal and run the command. 06:13.330 --> 06:21.690 Go run go routines Dok Go we've just scratched the surface of concurrent programming and go but we can 06:21.690 --> 06:26.310 already see that it can be quite powerful but we definitely have to do something with that sleeping 06:26.310 --> 06:32.730 period wait groups can help us with this problem weight group comes in the synchronization package also 06:32.730 --> 06:38.220 called as the sync package to help us synchronize many concurrent go with T. 06:38.440 --> 06:43.360 It works very easily every time we have to wait for one guy waiting to finish we add one to the group 06:44.530 --> 06:49.940 and once all of them are added we asked the group to wait when the guy routine finishes it says done 06:50.210 --> 06:54.270 and the wait group will take one from the group let's add the code for this. 06:54.500 --> 06:57.740 This is the simplest possible example of a weight group. 06:57.740 --> 07:01.620 First we created a variable to hold it called the weight variable next. 07:01.760 --> 07:06.440 Before launching the new go routine we say to the weight group hey you have to wait for one thing to 07:06.440 --> 07:09.360 finish by using the white dot add one method. 07:09.380 --> 07:11.880 Now we can launch the one that the weight group has to wait for. 07:11.960 --> 07:17.090 Which in this case is the previous go routine that prints hello world and so is done by using the white 07:17.090 --> 07:20.190 dot done method at the end of the go routine. 07:20.200 --> 07:25.780 Finally we indicate to the weight group to wait we have to remember that the function white dot Waits 07:25.780 --> 07:32.210 was probably executed before the go routine now save the file and run the code again. 07:32.570 --> 07:40.510 Go run weight group dot go now it just weights the necessary time and not one millisecond more before 07:40.570 --> 07:46.240 exiting the application remember that when we use the add value method we add entities to the weight 07:46.240 --> 07:53.060 group and when we used a done method we subtract one actually the add function takes it down today. 07:53.060 --> 07:56.550 Now let me show you another code which is equivalent to the previous one. 07:56.870 --> 08:02.870 Open the White grouped dot file and let let's modify the line where we wrote the white dot done method. 08:02.870 --> 08:10.320 Now we can change it to white dot add in parentheses the value is minus 1 in this case we added 1 before 08:10.320 --> 08:16.980 launching the go routine and we added minus 1 that is subtracted 1 at the end of it if we know in advance 08:16.980 --> 08:22.470 how many go routines we're going to launch we can also call the add method just once let me show you 08:22.470 --> 08:28.560 another piece of code which you can use let's replace these lines in this example we're going to create 08:28.560 --> 08:33.750 five go routines are stated in the Go routines variable we know it's an advance so we can simply add 08:33.750 --> 08:38.070 them all to the weight group we're then going to launch the same amount of Go routine variables by using 08:38.070 --> 08:44.220 a for loop every time one go routine finishes it calls the done method of the weight group that is effectively 08:44.220 --> 08:49.480 waiting at the end of the main loop again in this case the code reaches the end of the main function 08:49.480 --> 08:54.610 before all go routines are launched if any and the weight group makes the execution of the main flow 08:54.610 --> 09:04.040 wait until all done messages are called say the file and let's run this small program go run weights 09:04.040 --> 09:10.680 group Dok Go we haven't mentioned it before but we passed the iteration index to each go routine as 09:10.680 --> 09:16.470 the parameter go routine I.D. to print it with a message Hello go routines you might also have noticed 09:16.470 --> 09:23.100 that they go routines aren't executed in order Orson in this video we've worked we've got routines in 09:23.100 --> 09:25.470 the next video we'll learn to use callbacks and go.