"The way of Golang's growth" concurrent Goroutine

Posted by Panz3r on Tue, 21 Dec 2021 02:51:41 +0100

Goroutine

1, Concurrent

Concurrent programming shows that the program is composed of several independent active units. In today's Internet, a web server may process thousands of requests at a time. While tablet computers and mobile phones render the user interface, the back end also synchronously calculates and processes network requests.
In go language, every concurrent activity is called goroutine, and in our most common main function, it is also a goroutine (main goroutine). Before that, the introduction syntax or programs we have seen are executed in sequence, but in the field of concurrent programming, we may be doubly confused if we obtain intuition from sequential programming.
Here we need to understand what concurrency is:
Encyclopedia: when there are multiple threads operating, if the system has only one CPU, it is impossible for it to carry out more than one thread at the same time. It can only divide the CPU running time into several time periods, and then allocate the time periods to each thread for execution. When the thread code of one time period runs, other threads are suspended This method is called concurrent.


(this is the running mode of ordinary functions. Main gives its control to the calling function, and finally returns it to main)

My understanding: for example, I take notes while taking online classes. When I take notes, I need to pause the online class and continue to watch the online class after my notes are finished. These two things can be regarded as a concurrent process.

(the collaborative process is: main and goroutine interact and give control to each other, just like two people, each doing their own things, and they also communicate with each other)

2, go keyword

When a program starts, there is only one goroutine to call main, which is called as the main goroutine. The new goroutine is created through the go keyword. See the following example:

func main() {
   for i := 0; i < 3; i++ {
   //Create goroutine with go keyword
   //Anonymous function
       go func() {
          for j := 3; j >= 0; j-- {
            fmt.Println("gorouting", j)
          }
       }()
    fmt.Println("gorouting mian:", i)
    //Control program running time
    time.Sleep(time.Microsecond)

   }
}

Of course, you can also take out anonymous functions:

package main

import (
   "fmt"
 "time")

func doWorker() {
     for j := 3; j >= 0; j-- {
        fmt.Println("gorouting", j)
     }
}

func main() {
   for i := 0; i < 3; i++ {
   //Create goroutine with go keyword
       go doWroker()
    fmt.Println("gorouting mian:", i)
    //Control program running time
    time.Sleep(time.Microsecond)
   }
}

Let's look at the print results first:

gorouting mian: 0
gorouting 3
gorouting 2
gorouting 1
gorouting 0
gorouting mian: 1
gorouting 3
gorouting 2
gorouting 1
gorouting 0
gorouting mian: 2
gorouting 3
gorouting 2
gorouting 1
gorouting 0

Second run:

gorouting mian: 0
gorouting mian: 1
gorouting 3
gorouting 2
gorouting 1
gorouting 0
gorouting 3
gorouting 2
gorouting 1
gorouting 0
gorouting mian: 2
gorouting 3
gorouting 2
gorouting 1
gorouting 0

Program explanation: in fact, it can be seen that the results of each run are different. When the program adds the first for, i=0 and runs to the keyword go, a new goroutine is created, but the program will not execute the new goroutine immediately. It will execute the rest of the code in main. In our example, this is the result of the first run, The same is true for the second run.

func main(){
     var a[10] int
     for i := 0; i < 10;i++{
         //Create goroutine with go keyword
         //Anonymous function
          go func(i int){
             for{
                a[i]++
             }
          }(i)
       }
    time.Sleep(time.Microsecond)
    fmt.Println(a)
}

Print results:

[39904 0 0 9122 0 7123 0 0 0 0]

Program explanation: a total of 10 goroutines were created in the for loop. Some goroutines were executed and some were still waiting. However, we didn't give the main goroutine much time, so some were killed by the main goroutine before execution, so we can understand the printing results.

3, goroutine switching point (possible)

goroutine may switch:

  1. I/O,select
  2. channel
  3. Waiting lock
  4. Function call (sometimes)
  5. runtime.Gosched

Topics: Go