I don't know if you noticed, this code if I run in two goroutines:
Package Mainimport ( "FMT") func loop (do chan bool) { for I: = 0; i <; i++ { FMT. Print (i) } true}func main () {done := Make (chan bool) go Loop (done) go Loop (done) <-done <-done}
The result of his output: 01234567890123456789
Go is not going to start a new goroutine to run the loop function. In the past, when we used a thread to do similar tasks, the thread of the system would be out of the way, showing the output in a random order. And goroutine Why is this output?
For parallelism and concurrency, the following diagram illustrates:
- Two queues, one coffee machine, that is the concurrency
- Two queues, two coffee machines, that's parallel
By default, all go Goroutines can only run in one thread.
If the current goroutine does not block, it will not give up the CPU to other goroutine, so the output of the above example will be a goroutine
The real parallel
In order to achieve true parallelism, runtime. Gomaxprocs (2) Try it.
Package Mainimport ( "FMT" "Runtime") Func loop (do chan bool) { for I: = 0; I < ; 100; i++ { fmt. Printf ("%d", i) } true}func main () { runtime. Gomaxprocs (2) Done := Make (chan bool) go Loop (do) go loop ( done) <-done <-done}
This will see that two goroutine will output data in a preemptive manner. We can also explicitly give up CPU time like this:
Package Mainimport ( "FMT" "Runtime") Func loop (do chan bool) { for I: = 0; I < ; 100; i++ { fmt. Printf ("%d", i) runtime. Gosched () /////give CPU time explicitly to other goroutine } true }func Main () { // runtime. Gomaxprocs (2)done : = Make (chan bool) go Loop (done) go to loop (done) <- Done <-done}
Summarize
As we can see from the example, by default, all Goroutine will run in a native thread.
In the same native thread, if the current goroutine does not block, it will not give up the CPU time to other goroutines of the same thread, this is the Go runtime on the Goroutine dispatch, we can also use the runtime package to manually dispatch.
When a goroutine is blocked, go automatically transfers other goroutines that are in the same system thread as the Goroutine to another system thread so that these goroutines do not block
Concurrency and parallelism of the Go language